1.1 --- a/core/smn_fakenatives.cpp Fri Mar 29 12:28:02 2013 -0400
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,454 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include <sh_list.h>
1.36 -#include <sh_string.h>
1.37 -#include "sm_trie.h"
1.38 -#include "sm_globals.h"
1.39 -#include "PluginSys.h"
1.40 -#include "sourcemod.h"
1.41 -#include "sm_stringutil.h"
1.42 -
1.43 -using namespace SourceHook;
1.44 -
1.45 -static cell_t s_curparams[SP_MAX_EXEC_PARAMS+1];
1.46 -static FakeNative *s_curnative = NULL;
1.47 -static IPluginContext *s_curcaller = NULL;
1.48 -
1.49 -cell_t FakeNativeRouter(IPluginContext *pContext, const cell_t *params, void *pData)
1.50 -{
1.51 - FakeNative *native = (FakeNative *)pData;
1.52 -
1.53 - /* Check if too many parameters were passed */
1.54 - if (params[0] > SP_MAX_EXEC_PARAMS)
1.55 - {
1.56 - return pContext->ThrowNativeError("Called native with too many parameters (%d>%d)", params[9], SP_MAX_EXEC_PARAMS);
1.57 - }
1.58 -
1.59 - /* Check if the native is paused */
1.60 - if (native->ctx->GetRuntime()->IsPaused())
1.61 - {
1.62 - return pContext->ThrowNativeError("Plugin owning this native is currently paused.");
1.63 - }
1.64 -
1.65 - CPlugin *pCaller = g_PluginSys.GetPluginByCtx(pContext->GetContext());
1.66 -
1.67 - /* Save any old data on the stack */
1.68 - FakeNative *pSaveNative = s_curnative;
1.69 - IPluginContext *pSaveCaller = s_curcaller;
1.70 - cell_t save_params[SP_MAX_EXEC_PARAMS+1];
1.71 - if (pSaveNative != NULL)
1.72 - {
1.73 - /* Copy all old parameters */
1.74 - for (cell_t i=0; i<=s_curparams[0]; i++)
1.75 - {
1.76 - save_params[i] = s_curparams[i];
1.77 - }
1.78 - }
1.79 -
1.80 - /* Save the current parameters */
1.81 - s_curnative = native;
1.82 - s_curcaller = pContext;
1.83 - for (cell_t i=0; i<=params[0]; i++)
1.84 - {
1.85 - s_curparams[i] = params[i];
1.86 - }
1.87 -
1.88 - /* Push info and execute. */
1.89 - cell_t result = 0;
1.90 - native->call->PushCell(pCaller->GetMyHandle());
1.91 - native->call->PushCell(params[0]);
1.92 - int error;
1.93 - if ((error=native->call->Execute(&result)) != SP_ERROR_NONE)
1.94 - {
1.95 - if (pContext->GetLastNativeError() == SP_ERROR_NONE)
1.96 - {
1.97 - pContext->ThrowNativeErrorEx(error, "Error encountered while processing a dynamic native");
1.98 - }
1.99 - }
1.100 -
1.101 - /* Restore everything from the stack if necessary */
1.102 - s_curnative = pSaveNative;
1.103 - s_curcaller = pSaveCaller;
1.104 - if (pSaveNative != NULL)
1.105 - {
1.106 - for (cell_t i=0; i<=save_params[0]; i++)
1.107 - {
1.108 - s_curparams[i] = save_params[i];
1.109 - }
1.110 - }
1.111 -
1.112 - return result;
1.113 -}
1.114 -
1.115 -static cell_t CreateNative(IPluginContext *pContext, const cell_t *params)
1.116 -{
1.117 - char *name;
1.118 - CPlugin *pPlugin;
1.119 -
1.120 - pContext->LocalToString(params[1], &name);
1.121 -
1.122 - IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
1.123 - if (!pFunction)
1.124 - {
1.125 - return pContext->ThrowNativeError("Function %x is not a valid function", params[2]);
1.126 - }
1.127 -
1.128 - pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext());
1.129 -
1.130 - if (!pPlugin->AddFakeNative(pFunction, name, FakeNativeRouter))
1.131 - {
1.132 - return pContext->ThrowNativeError("Fatal error creating dynamic native!");
1.133 - }
1.134 -
1.135 - return 1;
1.136 -}
1.137 -
1.138 -static cell_t ThrowNativeError(IPluginContext *pContext, const cell_t *params)
1.139 -{
1.140 - if (!s_curnative || (s_curnative->ctx != pContext))
1.141 - {
1.142 - return pContext->ThrowNativeError("Not called from inside a native function");
1.143 - }
1.144 -
1.145 - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE);
1.146 -
1.147 - char buffer[512];
1.148 -
1.149 - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2);
1.150 -
1.151 - if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1.152 - {
1.153 - s_curcaller->ThrowNativeError("Error encountered while processing a dynamic native");
1.154 - } else {
1.155 - s_curcaller->ThrowNativeErrorEx(params[1], "%s", buffer);
1.156 - }
1.157 -
1.158 - return 0;
1.159 -}
1.160 -
1.161 -static cell_t GetNativeStringLength(IPluginContext *pContext, const cell_t *params)
1.162 -{
1.163 - if (!s_curnative || (s_curnative->ctx != pContext))
1.164 - {
1.165 - return pContext->ThrowNativeError("Not called from inside a native function");
1.166 - }
1.167 -
1.168 - cell_t param = params[1];
1.169 - if (param < 1 || param > s_curparams[0])
1.170 - {
1.171 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
1.172 - }
1.173 -
1.174 - int err;
1.175 - char *str;
1.176 - if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE)
1.177 - {
1.178 - return err;
1.179 - }
1.180 -
1.181 - cell_t *addr;
1.182 - pContext->LocalToPhysAddr(params[2], &addr);
1.183 - *addr = (cell_t)strlen(str);
1.184 -
1.185 - return SP_ERROR_NONE;
1.186 -}
1.187 -
1.188 -static cell_t GetNativeString(IPluginContext *pContext, const cell_t *params)
1.189 -{
1.190 - if (!s_curnative || (s_curnative->ctx != pContext))
1.191 - {
1.192 - return pContext->ThrowNativeError("Not called from inside a native function");
1.193 - }
1.194 -
1.195 - cell_t param = params[1];
1.196 - if (param < 1 || param > s_curparams[0])
1.197 - {
1.198 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
1.199 - }
1.200 -
1.201 - int err;
1.202 - char *str;
1.203 - if ((err=s_curcaller->LocalToString(s_curparams[param], &str)) != SP_ERROR_NONE)
1.204 - {
1.205 - return err;
1.206 - }
1.207 -
1.208 - size_t bytes = 0;
1.209 - pContext->StringToLocalUTF8(params[2], params[3], str, &bytes);
1.210 -
1.211 - cell_t *addr;
1.212 - pContext->LocalToPhysAddr(params[4], &addr);
1.213 - *addr = (cell_t)bytes;
1.214 -
1.215 - return SP_ERROR_NONE;
1.216 -}
1.217 -
1.218 -static cell_t SetNativeString(IPluginContext *pContext, const cell_t *params)
1.219 -{
1.220 - if (!s_curnative || (s_curnative->ctx != pContext))
1.221 - {
1.222 - return pContext->ThrowNativeError("Not called from inside a native function");
1.223 - }
1.224 -
1.225 - cell_t param = params[1];
1.226 - if (param < 1 || param > s_curparams[0])
1.227 - {
1.228 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
1.229 - }
1.230 -
1.231 - char *str;
1.232 - pContext->LocalToString(params[2], &str);
1.233 -
1.234 - int err;
1.235 - size_t bytes = 0;
1.236 - if (params[4])
1.237 - {
1.238 - err = s_curcaller->StringToLocalUTF8(s_curparams[param], params[3], str, &bytes);
1.239 - } else {
1.240 - err = s_curcaller->StringToLocal(s_curparams[param], params[3], str);
1.241 - /* Eww */
1.242 - bytes = strlen(str);
1.243 - if (bytes >= (size_t)params[3])
1.244 - {
1.245 - bytes = params[3] - 1;
1.246 - }
1.247 - }
1.248 -
1.249 - if (err != SP_ERROR_NONE)
1.250 - {
1.251 - return err;
1.252 - }
1.253 -
1.254 - cell_t *addr;
1.255 - pContext->LocalToPhysAddr(params[5], &addr);
1.256 - *addr = (cell_t)bytes;
1.257 -
1.258 - return SP_ERROR_NONE;
1.259 -}
1.260 -
1.261 -static cell_t GetNativeCell(IPluginContext *pContext, const cell_t *params)
1.262 -{
1.263 - if (!s_curnative || (s_curnative->ctx != pContext))
1.264 - {
1.265 - return pContext->ThrowNativeError("Not called from inside a native function");
1.266 - }
1.267 -
1.268 - cell_t param = params[1];
1.269 - if (param < 1 || param > s_curparams[0])
1.270 - {
1.271 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
1.272 - }
1.273 -
1.274 - return s_curparams[param];
1.275 -}
1.276 -
1.277 -static cell_t GetNativeCellRef(IPluginContext *pContext, const cell_t *params)
1.278 -{
1.279 - if (!s_curnative || (s_curnative->ctx != pContext))
1.280 - {
1.281 - return pContext->ThrowNativeError("Not called from inside a native function");
1.282 - }
1.283 -
1.284 - cell_t param = params[1];
1.285 - if (param < 1 || param > s_curparams[0])
1.286 - {
1.287 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
1.288 - }
1.289 -
1.290 - cell_t *addr;
1.291 - if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE)
1.292 - {
1.293 - return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value");
1.294 - }
1.295 -
1.296 - return *addr;
1.297 -}
1.298 -
1.299 -static cell_t SetNativeCellRef(IPluginContext *pContext, const cell_t *params)
1.300 -{
1.301 - if (!s_curnative || (s_curnative->ctx != pContext))
1.302 - {
1.303 - return pContext->ThrowNativeError("Not called from inside a native function");
1.304 - }
1.305 -
1.306 - cell_t param = params[1];
1.307 - if (param < 1 || param > s_curparams[0])
1.308 - {
1.309 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
1.310 - }
1.311 -
1.312 - cell_t *addr;
1.313 - if (s_curcaller->LocalToPhysAddr(s_curparams[param], &addr) != SP_ERROR_NONE)
1.314 - {
1.315 - return s_curcaller->ThrowNativeErrorEx(SP_ERROR_INVALID_ADDRESS, "Invalid address value");
1.316 - }
1.317 -
1.318 - *addr = params[2];
1.319 -
1.320 - return 1;
1.321 -}
1.322 -
1.323 -static cell_t GetNativeArray(IPluginContext *pContext, const cell_t *params)
1.324 -{
1.325 - if (!s_curnative || (s_curnative->ctx != pContext))
1.326 - {
1.327 - return pContext->ThrowNativeError("Not called from inside a native function");
1.328 - }
1.329 -
1.330 - cell_t param = params[1];
1.331 - if (param < 1 || param > s_curparams[0])
1.332 - {
1.333 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
1.334 - }
1.335 -
1.336 - int err;
1.337 - cell_t *addr;
1.338 - if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE)
1.339 - {
1.340 - return err;
1.341 - }
1.342 -
1.343 - cell_t *src;
1.344 - pContext->LocalToPhysAddr(params[2], &src);
1.345 -
1.346 - memcpy(src, addr, sizeof(cell_t) * params[3]);
1.347 -
1.348 - return SP_ERROR_NONE;
1.349 -}
1.350 -
1.351 -static cell_t SetNativeArray(IPluginContext *pContext, const cell_t *params)
1.352 -{
1.353 - if (!s_curnative || (s_curnative->ctx != pContext))
1.354 - {
1.355 - return pContext->ThrowNativeError("Not called from inside a native function");
1.356 - }
1.357 -
1.358 - cell_t param = params[1];
1.359 - if (param < 1 || param > s_curparams[0])
1.360 - {
1.361 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", param);
1.362 - }
1.363 -
1.364 - int err;
1.365 - cell_t *addr;
1.366 - if ((err=s_curcaller->LocalToPhysAddr(s_curparams[param], &addr)) != SP_ERROR_NONE)
1.367 - {
1.368 - return err;
1.369 - }
1.370 -
1.371 - cell_t *src;
1.372 - pContext->LocalToPhysAddr(params[2], &src);
1.373 -
1.374 - memcpy(addr, src, sizeof(cell_t) * params[3]);
1.375 -
1.376 - return SP_ERROR_NONE;
1.377 -}
1.378 -
1.379 -static cell_t FormatNativeString(IPluginContext *pContext, const cell_t *params)
1.380 -{
1.381 - if (!s_curnative || (s_curnative->ctx != pContext))
1.382 - {
1.383 - return pContext->ThrowNativeError("Not called from inside a native function");
1.384 - }
1.385 -
1.386 - int out_param = params[1];
1.387 - int fmt_param = params[2];
1.388 - int var_param = params[3];
1.389 -
1.390 - /* Validate input */
1.391 - if (out_param && (out_param < 1 || out_param > s_curparams[0]))
1.392 - {
1.393 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", out_param);
1.394 - }
1.395 - if (fmt_param && (fmt_param < 1 || fmt_param > s_curparams[0]))
1.396 - {
1.397 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param);
1.398 - }
1.399 - if (var_param && (var_param < 1 || var_param > s_curparams[0] + 1))
1.400 - {
1.401 - return pContext->ThrowNativeErrorEx(SP_ERROR_PARAM, "Invalid parameter number: %d", fmt_param);
1.402 - }
1.403 -
1.404 - /* Get buffer information */
1.405 - int err;
1.406 - char *output_buffer;
1.407 - char *format_buffer;
1.408 -
1.409 - if (out_param)
1.410 - {
1.411 - if ((err=s_curcaller->LocalToString(s_curparams[out_param], &output_buffer)) != SP_ERROR_NONE)
1.412 - {
1.413 - return err;
1.414 - }
1.415 - } else {
1.416 - pContext->LocalToString(params[6], &output_buffer);
1.417 - }
1.418 -
1.419 - if (fmt_param)
1.420 - {
1.421 - if ((err=s_curcaller->LocalToString(s_curparams[fmt_param], &format_buffer)) != SP_ERROR_NONE)
1.422 - {
1.423 - return err;
1.424 - }
1.425 - } else {
1.426 - pContext->LocalToString(params[7], &format_buffer);
1.427 - }
1.428 -
1.429 - /* Get maximum length */
1.430 - size_t maxlen = (size_t)params[4];
1.431 -
1.432 - /* Do the format */
1.433 - size_t written = atcprintf(output_buffer, maxlen, format_buffer, s_curcaller, s_curparams, &var_param);
1.434 -
1.435 - cell_t *addr;
1.436 - pContext->LocalToPhysAddr(params[5], &addr);
1.437 - *addr = (cell_t)written;
1.438 -
1.439 - return s_curcaller->GetLastNativeError();
1.440 -}
1.441 -
1.442 -//tee hee
1.443 -REGISTER_NATIVES(nativeNatives)
1.444 -{
1.445 - {"CreateNative", CreateNative},
1.446 - {"GetNativeArray", GetNativeArray},
1.447 - {"GetNativeCell", GetNativeCell},
1.448 - {"GetNativeCellRef", GetNativeCellRef},
1.449 - {"GetNativeString", GetNativeString},
1.450 - {"GetNativeStringLength", GetNativeStringLength},
1.451 - {"FormatNativeString", FormatNativeString},
1.452 - {"ThrowNativeError", ThrowNativeError},
1.453 - {"SetNativeArray", SetNativeArray},
1.454 - {"SetNativeCellRef", SetNativeCellRef},
1.455 - {"SetNativeString", SetNativeString},
1.456 - {NULL, NULL},
1.457 -};