diff -r 4edce76aefe3 -r 4c93f74cae51 core/smn_fakenatives.cpp --- a/core/smn_fakenatives.cpp Fri Mar 29 12:28:02 2013 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,454 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include -#include "sm_trie.h" -#include "sm_globals.h" -#include "PluginSys.h" -#include "sourcemod.h" -#include "sm_stringutil.h" - -using namespace SourceHook; - -static cell_t s_curparams[SP_MAX_EXEC_PARAMS+1]; -static FakeNative *s_curnative = NULL; -static IPluginContext *s_curcaller = NULL; - -cell_t FakeNativeRouter(IPluginContext *pContext, const cell_t *params, void *pData) -{ - FakeNative *native = (FakeNative *)pData; - - /* Check if too many parameters were passed */ - if (params[0] > SP_MAX_EXEC_PARAMS) - { - return pContext->ThrowNativeError("Called native with too many parameters (%d>%d)", params[9], SP_MAX_EXEC_PARAMS); - } - - /* Check if the native is paused */ - if (native->ctx->GetRuntime()->IsPaused()) - { - return pContext->ThrowNativeError("Plugin owning this native is currently paused."); - } - - CPlugin *pCaller = g_PluginSys.GetPluginByCtx(pContext->GetContext()); - - /* Save any old data on the stack */ - FakeNative *pSaveNative = s_curnative; - IPluginContext *pSaveCaller = s_curcaller; - cell_t save_params[SP_MAX_EXEC_PARAMS+1]; - if (pSaveNative != NULL) - { - /* Copy all old parameters */ - for (cell_t i=0; i<=s_curparams[0]; i++) - { - save_params[i] = s_curparams[i]; - } - } - - /* Save the current parameters */ - s_curnative = native; - s_curcaller = pContext; - for (cell_t i=0; i<=params[0]; i++) - { - s_curparams[i] = params[i]; - } - - /* Push info and execute. */ - cell_t result = 0; - native->call->PushCell(pCaller->GetMyHandle()); - native->call->PushCell(params[0]); - int error; - if ((error=native->call->Execute(&result)) != SP_ERROR_NONE) - { - if (pContext->GetLastNativeError() == SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(error, "Error encountered while processing a dynamic native"); - } - } - - /* Restore everything from the stack if necessary */ - s_curnative = pSaveNative; - s_curcaller = pSaveCaller; - if (pSaveNative != NULL) - { - for (cell_t i=0; i<=save_params[0]; i++) - { - s_curparams[i] = save_params[i]; - } - } - - return result; -} - -static cell_t CreateNative(IPluginContext *pContext, const cell_t *params) -{ - char *name; - CPlugin *pPlugin; - - pContext->LocalToString(params[1], &name); - - IPluginFunction *pFunction = pContext->GetFunctionById(params[2]); - if (!pFunction) - { - return pContext->ThrowNativeError("Function %x is not a valid function", params[2]); - } - - pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext()); - - if (!pPlugin->AddFakeNative(pFunction, name, FakeNativeRouter)) - { - return pContext->ThrowNativeError("Fatal error creating dynamic native!"); - } - - return 1; -} - -static cell_t ThrowNativeError(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - - char buffer[512]; - - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - s_curcaller->ThrowNativeError("Error encountered while processing a dynamic native"); - } else { - s_curcaller->ThrowNativeErrorEx(params[1], "%s", buffer); - } - - return 0; -} - -static cell_t GetNativeStringLength(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - cell_t param = params[1]; - if (param < 1 || param > s_curparams[0]) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param); - } - - int err; - char *str; - if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE) - { - return err; - } - - cell_t *addr; - pContext->LocalToPhysAddr(params[2], &addr); - *addr = (cell_t)strlen(str); - - return SP_ERROR_NONE; -} - -static cell_t GetNativeString(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - cell_t param = params[1]; - if (param < 1 || param > s_curparams[0]) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param); - } - - int err; - char *str; - if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE) - { - return err; - } - - size_t bytes = 0; - pContext->StringToLocalUTF8(params[2], params[3], str, &bytes); - - cell_t *addr; - pContext->LocalToPhysAddr(params[4], &addr); - *addr = (cell_t)bytes; - - return SP_ERROR_NONE; -} - -static cell_t SetNativeString(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - cell_t param = params[1]; - if (param < 1 || param > s_curparams[0]) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param); - } - - char *str; - pContext->LocalToString(params[2], &str); - - int err; - size_t bytes = 0; - if (params[4]) - { - err = s_curcaller->StringToLocalUTF8(s_curparams[param], params[3], str, &bytes); - } else { - err = s_curcaller->StringToLocal(s_curparams[param], params[3], str); - /* Eww */ - bytes = strlen(str); - if (bytes >= (size_t)params[3]) - { - bytes = params[3] - 1; - } - } - - if (err != SP_ERROR_NONE) - { - return err; - } - - cell_t *addr; - pContext->LocalToPhysAddr(params[5], &addr); - *addr = (cell_t)bytes; - - return SP_ERROR_NONE; -} - -static cell_t GetNativeCell(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - cell_t param = params[1]; - if (param < 1 || param > s_curparams[0]) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param); - } - - return s_curparams[param]; -} - -static cell_t GetNativeCellRef(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - cell_t param = params[1]; - if (param < 1 || param > s_curparams[0]) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param); - } - - cell_t *addr; - if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE) - { - return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value"); - } - - return *addr; -} - -static cell_t SetNativeCellRef(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - cell_t param = params[1]; - if (param < 1 || param > s_curparams[0]) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param); - } - - cell_t *addr; - if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE) - { - return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value"); - } - - *addr = params[2]; - - return 1; -} - -static cell_t GetNativeArray(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - cell_t param = params[1]; - if (param < 1 || param > s_curparams[0]) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param); - } - - int err; - cell_t *addr; - if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE) - { - return err; - } - - cell_t *src; - pContext->LocalToPhysAddr(params[2], &src); - - memcpy(src, addr, sizeof(cell_t) * params[3]); - - return SP_ERROR_NONE; -} - -static cell_t SetNativeArray(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - cell_t param = params[1]; - if (param < 1 || param > s_curparams[0]) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param); - } - - int err; - cell_t *addr; - if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE) - { - return err; - } - - cell_t *src; - pContext->LocalToPhysAddr(params[2], &src); - - memcpy(addr, src, sizeof(cell_t) * params[3]); - - return SP_ERROR_NONE; -} - -static cell_t FormatNativeString(IPluginContext *pContext, const cell_t *params) -{ - if (!s_curnative || (s_curnative->ctx != pContext)) - { - return pContext->ThrowNativeError("Not called from inside a native function"); - } - - int out_param = params[1]; - int fmt_param = params[2]; - int var_param = params[3]; - - /* Validate input */ - if (out_param && (out_param < 1 || out_param > s_curparams[0])) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", out_param); - } - if (fmt_param && (fmt_param < 1 || fmt_param > s_curparams[0])) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param); - } - if (var_param && (var_param < 1 || var_param > s_curparams[0] + 1)) - { - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param); - } - - /* Get buffer information */ - int err; - char *output_buffer; - char *format_buffer; - - if (out_param) - { - if ((err=s_curcaller->LocalToString(s_curparams[out_param], &output_buffer)) != SP_ERROR_NONE) - { - return err; - } - } else { - pContext->LocalToString(params[6], &output_buffer); - } - - if (fmt_param) - { - if ((err=s_curcaller->LocalToString(s_curparams[fmt_param], &format_buffer)) != SP_ERROR_NONE) - { - return err; - } - } else { - pContext->LocalToString(params[7], &format_buffer); - } - - /* Get maximum length */ - size_t maxlen = (size_t)params[4]; - - /* Do the format */ - size_t written = atcprintf(output_buffer, maxlen, format_buffer, s_curcaller, s_curparams, &var_param); - - cell_t *addr; - pContext->LocalToPhysAddr(params[5], &addr); - *addr = (cell_t)written; - - return s_curcaller->GetLastNativeError(); -} - -//tee hee -REGISTER_NATIVES(nativeNatives) -{ - {"CreateNative", CreateNative}, - {"GetNativeArray", GetNativeArray}, - {"GetNativeCell", GetNativeCell}, - {"GetNativeCellRef", GetNativeCellRef}, - {"GetNativeString", GetNativeString}, - {"GetNativeStringLength", GetNativeStringLength}, - {"FormatNativeString", FormatNativeString}, - {"ThrowNativeError", ThrowNativeError}, - {"SetNativeArray", SetNativeArray}, - {"SetNativeCellRef", SetNativeCellRef}, - {"SetNativeString", SetNativeString}, - {NULL, NULL}, -};