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>
38 HandleType_t g_KeyValueType;
43 CStack<KeyValues *> pCurRoot;
46 class KeyValueNatives :
48 public IHandleTypeDispatch
51 void OnSourceModAllInitialized()
53 g_KeyValueType = g_HandleSys.CreateType("KeyValues", this, 0, NULL, NULL, g_pCoreIdent, NULL);
55 void OnSourceModShutdown()
57 g_HandleSys.RemoveType(g_KeyValueType, g_pCoreIdent);
60 void OnHandleDestroy(HandleType_t type, void *object)
62 KeyValueStack *pStk = reinterpret_cast<KeyValueStack *>(object);
63 pStk->pBase->deleteThis();
68 KeyValues *SourceModBase::ReadKeyValuesHandle(Handle_t hndl, HandleError *err, bool root)
75 sec.pIdentity = g_pCoreIdent;
77 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
89 *err = HandleError_None;
92 return (root) ? pStk->pBase : pStk->pCurRoot.front();
95 static cell_t smn_KvSetString(IPluginContext *pCtx, const cell_t *params)
97 Handle_t hndl = static_cast<Handle_t>(params[1]);
103 sec.pIdentity = g_pCoreIdent;
105 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
108 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
112 pCtx->LocalToStringNULL(params[2], &key);
113 pCtx->LocalToString(params[3], &value);
115 pStk->pCurRoot.front()->SetString(key, value);
120 static cell_t smn_KvSetNum(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);
139 pStk->pCurRoot.front()->SetInt(key, params[3]);
144 static cell_t smn_KvSetUInt64(IPluginContext *pCtx, const cell_t *params)
146 Handle_t hndl = static_cast<Handle_t>(params[1]);
152 sec.pIdentity = g_pCoreIdent;
154 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
157 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
163 pCtx->LocalToStringNULL(params[2], &key);
164 pCtx->LocalToPhysAddr(params[3], &addr);
166 value = static_cast<uint64>(*addr);
167 pStk->pCurRoot.front()->SetUint64(key, value);
172 static cell_t smn_KvSetFloat(IPluginContext *pCtx, const cell_t *params)
174 Handle_t hndl = static_cast<Handle_t>(params[1]);
180 sec.pIdentity = g_pCoreIdent;
182 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
185 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
189 pCtx->LocalToStringNULL(params[2], &key);
191 pStk->pCurRoot.front()->SetFloat(key, sp_ctof(params[3]));
196 static cell_t smn_KvSetColor(IPluginContext *pCtx, const cell_t *params)
198 Handle_t hndl = static_cast<Handle_t>(params[1]);
204 sec.pIdentity = g_pCoreIdent;
206 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
209 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
213 pCtx->LocalToStringNULL(params[2], &key);
215 Color color(params[3], params[4], params[5], params[6]);
216 pStk->pCurRoot.front()->SetColor(key, color);
221 static cell_t smn_KvSetVector(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);
240 pCtx->LocalToStringNULL(params[2], &key);
241 pCtx->LocalToPhysAddr(params[3], &vector);
243 UTIL_Format(buffer, sizeof(buffer), "%f %f %f", sp_ctof(vector[0]), sp_ctof(vector[1]), sp_ctof(vector[2]));
245 pStk->pCurRoot.front()->SetString(key, buffer);
250 static cell_t smn_KvGetString(IPluginContext *pCtx, const cell_t *params)
252 Handle_t hndl = static_cast<Handle_t>(params[1]);
258 sec.pIdentity = g_pCoreIdent;
260 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
263 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
267 char *key, *defvalue;
268 pCtx->LocalToStringNULL(params[2], &key);
269 pCtx->LocalToString(params[5], &defvalue);
271 value = pStk->pCurRoot.front()->GetString(key, defvalue);
272 pCtx->StringToLocalUTF8(params[3], params[4], value, NULL);
277 static cell_t smn_KvGetNum(IPluginContext *pCtx, const cell_t *params)
279 Handle_t hndl = static_cast<Handle_t>(params[1]);
285 sec.pIdentity = g_pCoreIdent;
287 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
290 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
295 pCtx->LocalToStringNULL(params[2], &key);
297 value = pStk->pCurRoot.front()->GetInt(key, params[3]);
302 static cell_t smn_KvGetFloat(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()->GetFloat(key, sp_ctof(params[3]));
324 return sp_ftoc(value);
327 static cell_t smn_KvGetColor(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 cell_t *r, *g, *b, *a;
346 pCtx->LocalToStringNULL(params[2], &key);
347 pCtx->LocalToPhysAddr(params[3], &r);
348 pCtx->LocalToPhysAddr(params[4], &g);
349 pCtx->LocalToPhysAddr(params[5], &b);
350 pCtx->LocalToPhysAddr(params[6], &a);
352 color = pStk->pCurRoot.front()->GetColor(key);
361 static cell_t smn_KvGetUInt64(IPluginContext *pCtx, const cell_t *params)
363 Handle_t hndl = static_cast<Handle_t>(params[1]);
369 sec.pIdentity = g_pCoreIdent;
371 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
374 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
378 cell_t *addr, *defvalue;
380 pCtx->LocalToStringNULL(params[2], &key);
381 pCtx->LocalToPhysAddr(params[3], &addr);
382 pCtx->LocalToPhysAddr(params[4], &defvalue);
384 value = pStk->pCurRoot.front()->GetUint64(key, static_cast<uint64>(*defvalue));
385 *reinterpret_cast<uint64 *>(addr) = value;
390 static cell_t smn_KvGetVector(IPluginContext *pCtx, const cell_t *params)
392 Handle_t hndl = static_cast<Handle_t>(params[1]);
398 sec.pIdentity = g_pCoreIdent;
400 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
403 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
408 cell_t *defvector, *outvector;
410 pCtx->LocalToStringNULL(params[2], &key);
411 pCtx->LocalToPhysAddr(params[3], &outvector);
412 pCtx->LocalToPhysAddr(params[4], &defvector);
414 UTIL_Format(buffer, sizeof(buffer), "%f %f %f", sp_ctof(defvector[0]), sp_ctof(defvector[1]), sp_ctof(defvector[2]));
416 value = pStk->pCurRoot.front()->GetString(key, buffer);
420 while (*value && components < 3)
422 while ((*value) && (*value == ' '))
439 for (; *value && isdigit(*value); ++value)
449 for (; *value && isdigit(*value); ++value)
451 out += (*value - '0') * factor;
456 out = (isnegative) ? -out : out;
457 outvector[components++] = sp_ftoc(out);
463 static cell_t smn_CreateKeyValues(IPluginContext *pCtx, const cell_t *params)
466 char *name, *firstkey, *firstvalue;
469 pCtx->LocalToString(params[1], &name);
470 pCtx->LocalToString(params[2], &firstkey);
471 pCtx->LocalToString(params[3], &firstvalue);
473 is_empty = (firstkey[0] == '\0');
474 pStk = new KeyValueStack;
475 pStk->pBase = new KeyValues(name, is_empty ? NULL : firstkey, (is_empty||(firstvalue[0]=='\0')) ? NULL : firstvalue);
476 pStk->pCurRoot.push(pStk->pBase);
478 return g_HandleSys.CreateHandle(g_KeyValueType, pStk, pCtx->GetIdentity(), g_pCoreIdent, NULL);
481 static cell_t smn_KvJumpToKey(IPluginContext *pCtx, const cell_t *params)
483 Handle_t hndl = static_cast<Handle_t>(params[1]);
490 sec.pIdentity = g_pCoreIdent;
492 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
495 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
498 pCtx->LocalToString(params[2], &name);
500 KeyValues *pSubKey = pStk->pCurRoot.front();
501 pSubKey = pSubKey->FindKey(name, (params[3]) ? true : false);
506 pStk->pCurRoot.push(pSubKey);
511 static cell_t smn_KvJumpToKeySymbol(IPluginContext *pCtx, const cell_t *params)
513 Handle_t hndl = static_cast<Handle_t>(params[1]);
519 sec.pIdentity = g_pCoreIdent;
521 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
524 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
527 KeyValues *pSubKey = pStk->pCurRoot.front();
528 pSubKey = pSubKey->FindKey(params[2]);
533 pStk->pCurRoot.push(pSubKey);
538 static cell_t smn_KvGotoFirstSubKey(IPluginContext *pCtx, const cell_t *params)
540 Handle_t hndl = static_cast<Handle_t>(params[1]);
546 sec.pIdentity = g_pCoreIdent;
548 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
551 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
554 KeyValues *pSubKey = pStk->pCurRoot.front();
555 KeyValues *pFirstSubKey;
558 pFirstSubKey = pSubKey->GetFirstTrueSubKey();
560 pFirstSubKey = pSubKey->GetFirstSubKey();
567 pStk->pCurRoot.push(pFirstSubKey);
572 static cell_t smn_KvGotoNextKey(IPluginContext *pCtx, const cell_t *params)
574 Handle_t hndl = static_cast<Handle_t>(params[1]);
580 sec.pIdentity = g_pCoreIdent;
582 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
585 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
588 KeyValues *pSubKey = pStk->pCurRoot.front();
591 pSubKey = pSubKey->GetNextTrueSubKey();
593 pSubKey = pSubKey->GetNextKey();
599 pStk->pCurRoot.pop();
600 pStk->pCurRoot.push(pSubKey);
605 static cell_t smn_KvJumpNextSubKey(IPluginContext *pCtx, const cell_t *params)
607 Handle_t hndl = static_cast<Handle_t>(params[1]);
613 sec.pIdentity = g_pCoreIdent;
615 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
618 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
621 KeyValues *pSubKey = pStk->pCurRoot.front();
622 KeyValues *pNextKey = pSubKey->GetNextKey();
627 pStk->pCurRoot.push(pNextKey);
632 static cell_t smn_KvGoBack(IPluginContext *pCtx, const cell_t *params)
634 Handle_t hndl = static_cast<Handle_t>(params[1]);
640 sec.pIdentity = g_pCoreIdent;
642 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
645 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
648 if (pStk->pCurRoot.size() == 1)
652 pStk->pCurRoot.pop();
657 static cell_t smn_KvRewind(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 while (pStk->pCurRoot.size() > 1)
675 pStk->pCurRoot.pop();
681 static cell_t smn_KvGetSectionName(IPluginContext *pCtx, const cell_t *params)
683 Handle_t hndl = static_cast<Handle_t>(params[1]);
689 sec.pIdentity = g_pCoreIdent;
691 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
694 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
697 KeyValues *pSection = pStk->pCurRoot.front();
698 const char *name = pSection->GetName();
703 pCtx->StringToLocalUTF8(params[2], params[3], name, NULL);
708 static cell_t smn_KvSetSectionName(IPluginContext *pCtx, const cell_t *params)
710 Handle_t hndl = static_cast<Handle_t>(params[1]);
717 sec.pIdentity = g_pCoreIdent;
719 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
722 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
725 pCtx->LocalToString(params[2], &name);
727 KeyValues *pSection = pStk->pCurRoot.front();
728 pSection->SetName(name);
733 static cell_t smn_KvGetDataType(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 return pStk->pCurRoot.front()->GetDataType(name);
755 static cell_t smn_KeyValuesToFile(IPluginContext *pCtx, const cell_t *params)
757 Handle_t hndl = static_cast<Handle_t>(params[1]);
764 sec.pIdentity = g_pCoreIdent;
766 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
769 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
772 pCtx->LocalToString(params[2], &path);
774 char realpath[PLATFORM_MAX_PATH];
775 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
777 return pStk->pCurRoot.front()->SaveToFile(basefilesystem, realpath);
780 static cell_t smn_FileToKeyValues(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()->LoadFromFile(basefilesystem, realpath);
805 static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
807 Handle_t hndl = static_cast<Handle_t>(params[1]);
813 sec.pIdentity = g_pCoreIdent;
815 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
818 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
821 pStk->pCurRoot.front()->UsesEscapeSequences(params[2] ? true : false);
826 static cell_t smn_KvNodesInStack(IPluginContext *pCtx, const cell_t *params)
828 Handle_t hndl = static_cast<Handle_t>(params[1]);
834 sec.pIdentity = g_pCoreIdent;
836 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
839 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
842 return pStk->pCurRoot.size() - 1;
845 static cell_t smn_KvDeleteThis(IPluginContext *pContext, const cell_t *params)
847 Handle_t hndl = static_cast<Handle_t>(params[1]);
853 sec.pIdentity = g_pCoreIdent;
855 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
858 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
861 if (pStk->pCurRoot.size() < 2)
866 KeyValues *pValues = pStk->pCurRoot.front();
867 pStk->pCurRoot.pop();
868 KeyValues *pRoot = pStk->pCurRoot.front();
870 /* We have to manually verify this since Valve sucks
871 * :TODO: make our own KeyValues.h file and make
872 * the sub stuff private so we can do this ourselves!
874 KeyValues *sub = pRoot->GetFirstSubKey();
879 KeyValues *pNext = pValues->GetNextKey();
880 pRoot->RemoveSubKey(pValues);
881 pValues->deleteThis();
884 pStk->pCurRoot.push(pNext);
890 sub = sub->GetNextKey();
893 /* Push this back on :( */
894 pStk->pCurRoot.push(pValues);
899 static cell_t smn_KvDeleteKey(IPluginContext *pContext, const cell_t *params)
901 Handle_t hndl = static_cast<Handle_t>(params[1]);
907 sec.pIdentity = g_pCoreIdent;
909 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
912 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
915 if (pStk->pCurRoot.size() < 2)
921 pContext->LocalToString(params[2], &keyName);
923 KeyValues *pRoot = pStk->pCurRoot.front();
924 KeyValues *pValues = pRoot->FindKey(keyName);
930 pRoot->RemoveSubKey(pValues);
931 pValues->deleteThis();
936 static cell_t smn_KvSavePosition(IPluginContext *pContext, const cell_t *params)
938 Handle_t hndl = static_cast<Handle_t>(params[1]);
944 sec.pIdentity = g_pCoreIdent;
946 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
949 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
952 if (pStk->pCurRoot.size() < 2)
957 KeyValues *pValues = pStk->pCurRoot.front();
958 pStk->pCurRoot.push(pValues);
963 static cell_t smn_CopySubkeys(IPluginContext *pContext, const cell_t *params)
965 Handle_t hndl_copied = static_cast<Handle_t>(params[1]);
966 Handle_t hndl_parent = static_cast<Handle_t>(params[2]);
969 KeyValueStack *pStk_copied, *pStk_parent;
972 sec.pIdentity = g_pCoreIdent;
974 if ((herr=g_HandleSys.ReadHandle(hndl_copied, g_KeyValueType, &sec, (void **)&pStk_copied))
977 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_copied, herr);
979 if ((herr=g_HandleSys.ReadHandle(hndl_parent, g_KeyValueType, &sec, (void **)&pStk_parent))
982 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl_parent, herr);
985 pStk_copied->pCurRoot.front()->CopySubkeys(pStk_parent->pCurRoot.front());
990 static cell_t smn_GetNameSymbol(IPluginContext *pContext, const cell_t *params)
992 Handle_t hndl = static_cast<Handle_t>(params[1]);
1000 sec.pIdentity = g_pCoreIdent;
1002 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
1003 != HandleError_None)
1005 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
1008 if (pStk->pCurRoot.size() < 2)
1013 pContext->LocalToString(params[2], &key);
1015 KeyValues *pKv = pStk->pCurRoot.front()->FindKey(key);
1020 pContext->LocalToPhysAddr(params[3], &val);
1021 *val = pKv->GetNameSymbol();
1026 static cell_t smn_FindKeyById(IPluginContext *pContext, const cell_t *params)
1028 Handle_t hndl = static_cast<Handle_t>(params[1]);
1031 KeyValueStack *pStk;
1034 sec.pIdentity = g_pCoreIdent;
1036 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
1037 != HandleError_None)
1039 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
1042 KeyValues *pKv = pStk->pCurRoot.front()->FindKey(params[2]);
1048 pContext->StringToLocalUTF8(params[3], params[4], pKv->GetName(), NULL);
1053 static cell_t smn_KvGetSectionSymbol(IPluginContext *pCtx, const cell_t *params)
1055 Handle_t hndl = static_cast<Handle_t>(params[1]);
1058 KeyValueStack *pStk;
1062 sec.pIdentity = g_pCoreIdent;
1064 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
1065 != HandleError_None)
1067 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
1070 KeyValues *pSection = pStk->pCurRoot.front();
1072 pCtx->LocalToPhysAddr(params[2], &val);
1073 *val = pSection->GetNameSymbol();
1083 static KeyValueNatives s_KeyValueNatives;
1085 REGISTER_NATIVES(keyvaluenatives)
1087 {"KvSetString", smn_KvSetString},
1088 {"KvSetNum", smn_KvSetNum},
1089 {"KvSetUInt64", smn_KvSetUInt64},
1090 {"KvSetFloat", smn_KvSetFloat},
1091 {"KvSetColor", smn_KvSetColor},
1092 {"KvGetString", smn_KvGetString},
1093 {"KvGetNum", smn_KvGetNum},
1094 {"KvGetFloat", smn_KvGetFloat},
1095 {"KvGetColor", smn_KvGetColor},
1096 {"KvGetUInt64", smn_KvGetUInt64},
1097 {"CreateKeyValues", smn_CreateKeyValues},
1098 {"KvJumpToKey", smn_KvJumpToKey},
1099 {"KvJumpToKeySymbol", smn_KvJumpToKeySymbol},
1100 {"KvGotoNextKey", smn_KvGotoNextKey},
1101 {"KvJumpFirstSubKey", smn_KvGotoFirstSubKey}, /* BACKWARDS COMPAT SHIM */
1102 {"KvGotoFirstSubKey", smn_KvGotoFirstSubKey},
1103 {"KvJumpNextSubKey", smn_KvJumpNextSubKey}, /* BACKWARDS COMPAT SHIM */
1104 {"KvGoBack", smn_KvGoBack},
1105 {"KvRewind", smn_KvRewind},
1106 {"KvGetSectionName", smn_KvGetSectionName},
1107 {"KvSetSectionName", smn_KvSetSectionName},
1108 {"KvGetDataType", smn_KvGetDataType},
1109 {"KeyValuesToFile", smn_KeyValuesToFile},
1110 {"FileToKeyValues", smn_FileToKeyValues},
1111 {"KvSetEscapeSequences", smn_KvSetEscapeSequences},
1112 {"KvDeleteThis", smn_KvDeleteThis},
1113 {"KvDeleteKey", smn_KvDeleteKey},
1114 {"KvNodesInStack", smn_KvNodesInStack},
1115 {"KvSavePosition", smn_KvSavePosition},
1116 {"KvCopySubkeys", smn_CopySubkeys},
1117 {"KvFindKeyById", smn_FindKeyById},
1118 {"KvGetNameSymbol", smn_GetNameSymbol},
1119 {"KvGetSectionSymbol", smn_KvGetSectionSymbol},
1120 {"KvGetVector", smn_KvGetVector},
1121 {"KvSetVector", smn_KvSetVector},