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>.
34 #include <sh_string.h>
36 #include "sm_globals.h"
37 #include "PluginSys.h"
38 #include "sourcemod.h"
39 #include "sm_stringutil.h"
41 using namespace SourceHook;
43 static cell_t s_curparams[SP_MAX_EXEC_PARAMS+1];
44 static FakeNative *s_curnative = NULL;
45 static IPluginContext *s_curcaller = NULL;
47 cell_t FakeNativeRouter(IPluginContext *pContext, const cell_t *params, void *pData)
49 FakeNative *native = (FakeNative *)pData;
51 /* Check if too many parameters were passed */
52 if (params[0] > SP_MAX_EXEC_PARAMS)
54 return pContext->ThrowNativeError("Called native with too many parameters (%d>%d)", params[9], SP_MAX_EXEC_PARAMS);
57 /* Check if the native is paused */
58 sp_context_t *pNativeCtx = native->ctx->GetContext();
59 if ((pNativeCtx->flags & SPFLAG_PLUGIN_PAUSED) == SPFLAG_PLUGIN_PAUSED)
61 return pContext->ThrowNativeError("Plugin owning this native is currently paused.");
64 CPlugin *pCaller = g_PluginSys.GetPluginByCtx(pContext->GetContext());
66 /* Save any old data on the stack */
67 FakeNative *pSaveNative = s_curnative;
68 IPluginContext *pSaveCaller = s_curcaller;
69 cell_t save_params[SP_MAX_EXEC_PARAMS+1];
70 if (pSaveNative != NULL)
72 /* Copy all old parameters */
73 for (cell_t i=0; i<=s_curparams[0]; i++)
75 save_params[i] = s_curparams[i];
79 /* Save the current parameters */
81 s_curcaller = pContext;
82 for (cell_t i=0; i<=params[0]; i++)
84 s_curparams[i] = params[i];
87 /* Push info and execute. */
89 native->call->PushCell(pCaller->GetMyHandle());
90 native->call->PushCell(params[0]);
92 if ((error=native->call->Execute(&result)) != SP_ERROR_NONE)
94 if (pContext->GetContext()->n_err == SP_ERROR_NONE)
96 pContext->ThrowNativeErrorEx(error, "Error encountered while processing a dynamic native");
100 /* Restore everything from the stack if necessary */
101 s_curnative = pSaveNative;
102 s_curcaller = pSaveCaller;
103 if (pSaveNative != NULL)
105 for (cell_t i=0; i<=save_params[0]; i++)
107 s_curparams[i] = save_params[i];
114 static cell_t CreateNative(IPluginContext *pContext, const cell_t *params)
117 pContext->LocalToString(params[1], &name);
119 IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
122 return pContext->ThrowNativeError("Function %x is not a valid function", params[2]);
125 if (!g_PluginSys.AddFakeNative(pFunction, name, FakeNativeRouter))
127 return pContext->ThrowNativeError("Fatal error creating dynamic native!");
133 static cell_t ThrowNativeError(IPluginContext *pContext, const cell_t *params)
135 if (!s_curnative || (s_curnative->ctx != pContext))
137 return pContext->ThrowNativeError("Not called from inside a native function");
140 g_SourceMod.SetGlobalTarget(LANG_SERVER);
144 g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
146 if (pContext->GetContext()->n_err != SP_ERROR_NONE)
148 s_curcaller->ThrowNativeError("Error encountered while processing a dynamic native");
150 s_curcaller->ThrowNativeErrorEx(params[1], "%s", buffer);
156 static cell_t GetNativeStringLength(IPluginContext *pContext, const cell_t *params)
158 if (!s_curnative || (s_curnative->ctx != pContext))
160 return pContext->ThrowNativeError("Not called from inside a native function");
163 cell_t param = params[1];
164 if (param < 1 || param > s_curparams[0])
166 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
171 if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE)
177 pContext->LocalToPhysAddr(params[2], &addr);
178 *addr = (cell_t)strlen(str);
180 return SP_ERROR_NONE;
183 static cell_t GetNativeString(IPluginContext *pContext, const cell_t *params)
185 if (!s_curnative || (s_curnative->ctx != pContext))
187 return pContext->ThrowNativeError("Not called from inside a native function");
190 cell_t param = params[1];
191 if (param < 1 || param > s_curparams[0])
193 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
198 if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE)
204 pContext->StringToLocalUTF8(params[2], params[3], str, &bytes);
207 pContext->LocalToPhysAddr(params[4], &addr);
208 *addr = (cell_t)bytes;
210 return SP_ERROR_NONE;
213 static cell_t SetNativeString(IPluginContext *pContext, const cell_t *params)
215 if (!s_curnative || (s_curnative->ctx != pContext))
217 return pContext->ThrowNativeError("Not called from inside a native function");
220 cell_t param = params[1];
221 if (param < 1 || param > s_curparams[0])
223 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
227 pContext->LocalToString(params[2], &str);
233 err = s_curcaller->StringToLocalUTF8(s_curparams[param], params[3], str, &bytes);
235 err = s_curcaller->StringToLocal(s_curparams[param], params[3], str);
238 if (bytes >= (size_t)params[3])
240 bytes = params[3] - 1;
244 if (err != SP_ERROR_NONE)
250 pContext->LocalToPhysAddr(params[5], &addr);
251 *addr = (cell_t)bytes;
253 return SP_ERROR_NONE;
256 static cell_t GetNativeCell(IPluginContext *pContext, const cell_t *params)
258 if (!s_curnative || (s_curnative->ctx != pContext))
260 return pContext->ThrowNativeError("Not called from inside a native function");
263 cell_t param = params[1];
264 if (param < 1 || param > s_curparams[0])
266 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
269 return s_curparams[param];
272 static cell_t GetNativeCellRef(IPluginContext *pContext, const cell_t *params)
274 if (!s_curnative || (s_curnative->ctx != pContext))
276 return pContext->ThrowNativeError("Not called from inside a native function");
279 cell_t param = params[1];
280 if (param < 1 || param > s_curparams[0])
282 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
286 if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE)
288 return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value");
294 static cell_t SetNativeCellRef(IPluginContext *pContext, const cell_t *params)
296 if (!s_curnative || (s_curnative->ctx != pContext))
298 return pContext->ThrowNativeError("Not called from inside a native function");
301 cell_t param = params[1];
302 if (param < 1 || param > s_curparams[0])
304 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
308 if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE)
310 return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value");
318 static cell_t GetNativeArray(IPluginContext *pContext, const cell_t *params)
320 if (!s_curnative || (s_curnative->ctx != pContext))
322 return pContext->ThrowNativeError("Not called from inside a native function");
325 cell_t param = params[1];
326 if (param < 1 || param > s_curparams[0])
328 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
333 if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE)
339 pContext->LocalToPhysAddr(params[2], &src);
341 memcpy(src, addr, sizeof(cell_t) * params[3]);
343 return SP_ERROR_NONE;
346 static cell_t SetNativeArray(IPluginContext *pContext, const cell_t *params)
348 if (!s_curnative || (s_curnative->ctx != pContext))
350 return pContext->ThrowNativeError("Not called from inside a native function");
353 cell_t param = params[1];
354 if (param < 1 || param > s_curparams[0])
356 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
361 if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE)
367 pContext->LocalToPhysAddr(params[2], &src);
369 memcpy(addr, src, sizeof(cell_t) * params[3]);
371 return SP_ERROR_NONE;
374 static cell_t FormatNativeString(IPluginContext *pContext, const cell_t *params)
376 if (!s_curnative || (s_curnative->ctx != pContext))
378 return pContext->ThrowNativeError("Not called from inside a native function");
381 int out_param = params[1];
382 int fmt_param = params[2];
383 int var_param = params[3];
386 if (out_param && (out_param < 1 || out_param > s_curparams[0]))
388 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", out_param);
390 if (fmt_param && (fmt_param < 1 || fmt_param > s_curparams[0]))
392 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param);
394 if (var_param && (var_param < 1 || var_param > s_curparams[0] + 1))
396 return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param);
399 /* Get buffer information */
406 if ((err=s_curcaller->LocalToString(s_curparams[out_param], &output_buffer)) != SP_ERROR_NONE)
411 pContext->LocalToString(params[6], &output_buffer);
416 if ((err=s_curcaller->LocalToString(s_curparams[fmt_param], &format_buffer)) != SP_ERROR_NONE)
421 pContext->LocalToString(params[7], &format_buffer);
424 /* Get maximum length */
425 size_t maxlen = (size_t)params[4];
428 size_t written = atcprintf(output_buffer, maxlen, format_buffer, s_curcaller, s_curparams, &var_param);
431 pContext->LocalToPhysAddr(params[5], &addr);
432 *addr = (cell_t)written;
434 return s_curcaller->GetContext()->n_err;
438 REGISTER_NATIVES(nativeNatives)
440 {"CreateNative", CreateNative},
441 {"GetNativeArray", GetNativeArray},
442 {"GetNativeCell", GetNativeCell},
443 {"GetNativeCellRef", GetNativeCellRef},
444 {"GetNativeString", GetNativeString},
445 {"GetNativeStringLength", GetNativeStringLength},
446 {"FormatNativeString", FormatNativeString},
447 {"ThrowNativeError", ThrowNativeError},
448 {"SetNativeArray", SetNativeArray},
449 {"SetNativeCellRef", SetNativeCellRef},
450 {"SetNativeString", SetNativeString},