Added check to make sure player are alive to perform sm_slap, sm_burn, sm_slay.
3 * ================================================================
5 * Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
6 * ================================================================
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License,
10 * version 3.0, as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to
21 * link the code of this program (as well as its derivative works) to
22 * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any
23 * Game MODs that run on software by the Valve Corporation. You must
24 * obey the GNU General Public License in all respects for all other
25 * code used. Additionally, AlliedModders LLC grants this exception
26 * to all derivative works. AlliedModders LLC defines further
27 * exceptions, found in LICENSE.txt (as of this writing, version
28 * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
33 #include "sourcemod.h"
34 #include "sourcemm_api.h"
35 #include "sm_stringutil.h"
36 #include "HandleSys.h"
37 #include <KeyValues.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();
69 KeyValues *SourceModBase::ReadKeyValuesHandle(Handle_t hndl, HandleError *err, bool root)
76 sec.pIdentity = g_pCoreIdent;
78 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
90 *err = HandleError_None;
93 return (root) ? pStk->pBase : pStk->pCurRoot.front();
96 static cell_t smn_KvSetString(IPluginContext *pCtx, const cell_t *params)
98 Handle_t hndl = static_cast<Handle_t>(params[1]);
104 sec.pIdentity = g_pCoreIdent;
106 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
109 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
113 pCtx->LocalToStringNULL(params[2], &key);
114 pCtx->LocalToString(params[3], &value);
116 pStk->pCurRoot.front()->SetString(key, value);
121 static cell_t smn_KvSetNum(IPluginContext *pCtx, const cell_t *params)
123 Handle_t hndl = static_cast<Handle_t>(params[1]);
129 sec.pIdentity = g_pCoreIdent;
131 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
134 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
138 pCtx->LocalToStringNULL(params[2], &key);
140 pStk->pCurRoot.front()->SetInt(key, params[3]);
145 static cell_t smn_KvSetUInt64(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);
164 pCtx->LocalToStringNULL(params[2], &key);
165 pCtx->LocalToPhysAddr(params[3], &addr);
167 value = static_cast<uint64>(*addr);
168 pStk->pCurRoot.front()->SetUint64(key, value);
173 static cell_t smn_KvSetFloat(IPluginContext *pCtx, const cell_t *params)
175 Handle_t hndl = static_cast<Handle_t>(params[1]);
181 sec.pIdentity = g_pCoreIdent;
183 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
186 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
190 pCtx->LocalToStringNULL(params[2], &key);
192 pStk->pCurRoot.front()->SetFloat(key, sp_ctof(params[3]));
197 static cell_t smn_KvSetColor(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 Color color(params[3], params[4], params[5], params[6]);
217 pStk->pCurRoot.front()->SetColor(key, color);
222 static cell_t smn_KvGetString(IPluginContext *pCtx, const cell_t *params)
224 Handle_t hndl = static_cast<Handle_t>(params[1]);
230 sec.pIdentity = g_pCoreIdent;
232 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
235 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
239 char *key, *defvalue;
240 pCtx->LocalToStringNULL(params[2], &key);
241 pCtx->LocalToString(params[5], &defvalue);
243 value = pStk->pCurRoot.front()->GetString(key, defvalue);
244 pCtx->StringToLocalUTF8(params[3], params[4], value, NULL);
249 static cell_t smn_KvGetNum(IPluginContext *pCtx, const cell_t *params)
251 Handle_t hndl = static_cast<Handle_t>(params[1]);
257 sec.pIdentity = g_pCoreIdent;
259 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
262 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
267 pCtx->LocalToStringNULL(params[2], &key);
269 value = pStk->pCurRoot.front()->GetInt(key, params[3]);
274 static cell_t smn_KvGetFloat(IPluginContext *pCtx, const cell_t *params)
276 Handle_t hndl = static_cast<Handle_t>(params[1]);
282 sec.pIdentity = g_pCoreIdent;
284 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
287 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
292 pCtx->LocalToStringNULL(params[2], &key);
294 value = pStk->pCurRoot.front()->GetFloat(key, sp_ctof(params[3]));
296 return sp_ftoc(value);
299 static cell_t smn_KvGetColor(IPluginContext *pCtx, const cell_t *params)
301 Handle_t hndl = static_cast<Handle_t>(params[1]);
307 sec.pIdentity = g_pCoreIdent;
309 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
312 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
317 cell_t *r, *g, *b, *a;
318 pCtx->LocalToStringNULL(params[2], &key);
319 pCtx->LocalToPhysAddr(params[3], &r);
320 pCtx->LocalToPhysAddr(params[4], &g);
321 pCtx->LocalToPhysAddr(params[5], &b);
322 pCtx->LocalToPhysAddr(params[6], &a);
324 color = pStk->pCurRoot.front()->GetColor(key);
333 static cell_t smn_KvGetUInt64(IPluginContext *pCtx, const cell_t *params)
335 Handle_t hndl = static_cast<Handle_t>(params[1]);
341 sec.pIdentity = g_pCoreIdent;
343 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
346 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
350 cell_t *addr, *defvalue;
352 pCtx->LocalToStringNULL(params[2], &key);
353 pCtx->LocalToPhysAddr(params[3], &addr);
354 pCtx->LocalToPhysAddr(params[4], &defvalue);
356 value = pStk->pCurRoot.front()->GetUint64(key, static_cast<uint64>(*defvalue));
357 *reinterpret_cast<uint64 *>(addr) = value;
362 static cell_t smn_CreateKeyValues(IPluginContext *pCtx, const cell_t *params)
365 char *name, *firstkey, *firstvalue;
368 pCtx->LocalToString(params[1], &name);
369 pCtx->LocalToString(params[2], &firstkey);
370 pCtx->LocalToString(params[3], &firstvalue);
372 is_empty = (firstkey[0] == '\0');
373 pStk = new KeyValueStack;
374 pStk->pBase = new KeyValues(name, is_empty ? NULL : firstkey, (is_empty||(firstvalue[0]=='\0')) ? NULL : firstvalue);
375 pStk->pCurRoot.push(pStk->pBase);
377 return g_HandleSys.CreateHandle(g_KeyValueType, pStk, pCtx->GetIdentity(), g_pCoreIdent, NULL);
380 static cell_t smn_KvJumpToKey(IPluginContext *pCtx, const cell_t *params)
382 Handle_t hndl = static_cast<Handle_t>(params[1]);
389 sec.pIdentity = g_pCoreIdent;
391 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
394 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
397 pCtx->LocalToString(params[2], &name);
399 KeyValues *pSubKey = pStk->pCurRoot.front();
400 pSubKey = pSubKey->FindKey(name, (params[3]) ? true : false);
405 pStk->pCurRoot.push(pSubKey);
410 static cell_t smn_KvGotoFirstSubKey(IPluginContext *pCtx, const cell_t *params)
412 Handle_t hndl = static_cast<Handle_t>(params[1]);
418 sec.pIdentity = g_pCoreIdent;
420 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
423 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
426 KeyValues *pSubKey = pStk->pCurRoot.front();
427 KeyValues *pFirstSubKey;
430 pFirstSubKey = pSubKey->GetFirstTrueSubKey();
432 pFirstSubKey = pSubKey->GetFirstSubKey();
439 pStk->pCurRoot.push(pFirstSubKey);
444 static cell_t smn_KvGotoNextKey(IPluginContext *pCtx, const cell_t *params)
446 Handle_t hndl = static_cast<Handle_t>(params[1]);
452 sec.pIdentity = g_pCoreIdent;
454 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
457 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
460 KeyValues *pSubKey = pStk->pCurRoot.front();
463 pSubKey = pSubKey->GetNextTrueSubKey();
465 pSubKey = pSubKey->GetNextKey();
471 pStk->pCurRoot.pop();
472 pStk->pCurRoot.push(pSubKey);
477 static cell_t smn_KvJumpNextSubKey(IPluginContext *pCtx, const cell_t *params)
479 Handle_t hndl = static_cast<Handle_t>(params[1]);
485 sec.pIdentity = g_pCoreIdent;
487 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
490 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
493 KeyValues *pSubKey = pStk->pCurRoot.front();
494 KeyValues *pNextKey = pSubKey->GetNextKey();
499 pStk->pCurRoot.push(pNextKey);
504 static cell_t smn_KvGoBack(IPluginContext *pCtx, const cell_t *params)
506 Handle_t hndl = static_cast<Handle_t>(params[1]);
512 sec.pIdentity = g_pCoreIdent;
514 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
517 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
520 if (pStk->pCurRoot.size() == 1)
524 pStk->pCurRoot.pop();
529 static cell_t smn_KvRewind(IPluginContext *pCtx, const cell_t *params)
531 Handle_t hndl = static_cast<Handle_t>(params[1]);
537 sec.pIdentity = g_pCoreIdent;
539 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
542 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
545 while (pStk->pCurRoot.size() > 1)
547 pStk->pCurRoot.pop();
553 static cell_t smn_KvGetSectionName(IPluginContext *pCtx, const cell_t *params)
555 Handle_t hndl = static_cast<Handle_t>(params[1]);
561 sec.pIdentity = g_pCoreIdent;
563 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
566 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
569 KeyValues *pSection = pStk->pCurRoot.front();
570 const char *name = pSection->GetName();
575 pCtx->StringToLocalUTF8(params[2], params[3], name, NULL);
580 static cell_t smn_KvSetSectionName(IPluginContext *pCtx, const cell_t *params)
582 Handle_t hndl = static_cast<Handle_t>(params[1]);
589 sec.pIdentity = g_pCoreIdent;
591 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
594 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
597 pCtx->LocalToString(params[2], &name);
599 KeyValues *pSection = pStk->pCurRoot.front();
600 pSection->SetName(name);
605 static cell_t smn_KvGetDataType(IPluginContext *pCtx, const cell_t *params)
607 Handle_t hndl = static_cast<Handle_t>(params[1]);
614 sec.pIdentity = g_pCoreIdent;
616 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
619 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
622 pCtx->LocalToString(params[2], &name);
624 return pStk->pCurRoot.front()->GetDataType(name);
627 static cell_t smn_KeyValuesToFile(IPluginContext *pCtx, const cell_t *params)
629 Handle_t hndl = static_cast<Handle_t>(params[1]);
636 sec.pIdentity = g_pCoreIdent;
638 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
641 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
644 pCtx->LocalToString(params[2], &path);
646 char realpath[PLATFORM_MAX_PATH];
647 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
649 return pStk->pCurRoot.front()->SaveToFile(basefilesystem, realpath);
652 static cell_t smn_FileToKeyValues(IPluginContext *pCtx, const cell_t *params)
654 Handle_t hndl = static_cast<Handle_t>(params[1]);
661 sec.pIdentity = g_pCoreIdent;
663 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
666 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
669 pCtx->LocalToString(params[2], &path);
671 char realpath[PLATFORM_MAX_PATH];
672 g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
674 return pStk->pCurRoot.front()->LoadFromFile(basefilesystem, realpath);
677 static cell_t smn_KvSetEscapeSequences(IPluginContext *pCtx, const cell_t *params)
679 Handle_t hndl = static_cast<Handle_t>(params[1]);
685 sec.pIdentity = g_pCoreIdent;
687 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
690 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
693 pStk->pCurRoot.front()->UsesEscapeSequences(params[2] ? true : false);
698 static cell_t smn_KvNodesInStack(IPluginContext *pCtx, const cell_t *params)
700 Handle_t hndl = static_cast<Handle_t>(params[1]);
706 sec.pIdentity = g_pCoreIdent;
708 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
711 return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
714 return pStk->pCurRoot.size() - 1;
717 static cell_t smn_KvDeleteThis(IPluginContext *pContext, const cell_t *params)
719 Handle_t hndl = static_cast<Handle_t>(params[1]);
725 sec.pIdentity = g_pCoreIdent;
727 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
730 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
733 if (pStk->pCurRoot.size() < 2)
738 KeyValues *pValues = pStk->pCurRoot.front();
739 pStk->pCurRoot.pop();
740 KeyValues *pRoot = pStk->pCurRoot.front();
742 /* We have to manually verify this since Valve sucks
743 * :TODO: make our own KeyValues.h file and make
744 * the sub stuff private so we can do this ourselves!
746 KeyValues *sub = pRoot->GetFirstSubKey();
751 KeyValues *pNext = pValues->GetNextKey();
752 pRoot->RemoveSubKey(pValues);
753 pValues->deleteThis();
756 pStk->pCurRoot.push(pNext);
762 sub = sub->GetNextKey();
765 /* Push this back on :( */
766 pStk->pCurRoot.push(pValues);
771 static cell_t smn_KvDeleteKey(IPluginContext *pContext, const cell_t *params)
773 Handle_t hndl = static_cast<Handle_t>(params[1]);
779 sec.pIdentity = g_pCoreIdent;
781 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
784 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
787 if (pStk->pCurRoot.size() < 2)
793 pContext->LocalToString(params[2], &keyName);
795 KeyValues *pRoot = pStk->pCurRoot.front();
796 KeyValues *pValues = pRoot->FindKey(keyName);
802 pRoot->RemoveSubKey(pValues);
803 pValues->deleteThis();
808 static cell_t smn_KvSavePosition(IPluginContext *pContext, const cell_t *params)
810 Handle_t hndl = static_cast<Handle_t>(params[1]);
816 sec.pIdentity = g_pCoreIdent;
818 if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
821 return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
824 if (pStk->pCurRoot.size() < 2)
829 KeyValues *pValues = pStk->pCurRoot.front();
830 pStk->pCurRoot.push(pValues);
835 static KeyValueNatives s_KeyValueNatives;
837 REGISTER_NATIVES(keyvaluenatives)
839 {"KvSetString", smn_KvSetString},
840 {"KvSetNum", smn_KvSetNum},
841 {"KvSetUInt64", smn_KvSetUInt64},
842 {"KvSetFloat", smn_KvSetFloat},
843 {"KvSetColor", smn_KvSetColor},
844 {"KvGetString", smn_KvGetString},
845 {"KvGetNum", smn_KvGetNum},
846 {"KvGetFloat", smn_KvGetFloat},
847 {"KvGetColor", smn_KvGetColor},
848 {"KvGetUInt64", smn_KvGetUInt64},
849 {"CreateKeyValues", smn_CreateKeyValues},
850 {"KvJumpToKey", smn_KvJumpToKey},
851 {"KvGotoNextKey", smn_KvGotoNextKey},
852 {"KvJumpFirstSubKey", smn_KvGotoFirstSubKey}, /* BACKWARDS COMPAT SHIM */
853 {"KvGotoFirstSubKey", smn_KvGotoFirstSubKey},
854 {"KvJumpNextSubKey", smn_KvJumpNextSubKey}, /* BACKWARDS COMPAT SHIM */
855 {"KvGoBack", smn_KvGoBack},
856 {"KvRewind", smn_KvRewind},
857 {"KvGetSectionName", smn_KvGetSectionName},
858 {"KvSetSectionName", smn_KvSetSectionName},
859 {"KvGetDataType", smn_KvGetDataType},
860 {"KeyValuesToFile", smn_KeyValuesToFile},
861 {"FileToKeyValues", smn_FileToKeyValues},
862 {"KvSetEscapeSequences", smn_KvSetEscapeSequences},
863 {"KvDeleteThis", smn_KvDeleteThis},
864 {"KvDeleteKey", smn_KvDeleteKey},
865 {"KvNodesInStack", smn_KvNodesInStack},
866 {"KvSavePosition", smn_KvSavePosition},