Dear me, I should have committed this long ago...
Dear me, I should have committed this long ago...
1) Added natives to create and manipulate global and private forward
2) Added natives to call forwards and functions
3) Added an IChanageableForward::RemoveFunction overload for convenience or something
4) Added test suite plugins for functions and forwards
5) Some random touch-ups to some include files
1.1 --- a/core/msvc8/sourcemod_mm.vcproj Thu Mar 15 22:32:45 2007 +0000
1.2 +++ b/core/msvc8/sourcemod_mm.vcproj Fri Mar 16 06:54:24 2007 +0000
1.3 @@ -726,6 +726,10 @@
1.4 >
1.5 </File>
1.6 <File
1.7 + RelativePath="..\smn_functions.cpp"
1.8 + >
1.9 + </File>
1.10 + <File
1.11 RelativePath="..\smn_halflife.cpp"
1.12 >
1.13 </File>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/core/smn_functions.cpp Fri Mar 16 06:54:24 2007 +0000
2.3 @@ -0,0 +1,590 @@
2.4 +/**
2.5 +* ===============================================================
2.6 +* SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
2.7 +* ===============================================================
2.8 +*
2.9 +* This file is not open source and may not be copied without explicit
2.10 +* written permission of AlliedModders LLC. This file may not be redistributed
2.11 +* in whole or significant part.
2.12 +* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
2.13 +*
2.14 +* Version: $Id$
2.15 +*/
2.16 +
2.17 +#include "sm_globals.h"
2.18 +#include "PluginSys.h"
2.19 +#include "ForwardSys.h"
2.20 +#include "HandleSys.h"
2.21 +
2.22 +HandleType_t g_GlobalFwdType = 0;
2.23 +HandleType_t g_PrivateFwdType = 0;
2.24 +
2.25 +static bool s_CallStarted = false;
2.26 +static ICallable *s_pCallable = NULL;
2.27 +static IPluginFunction *s_pFunction = NULL;
2.28 +static IForward *s_pForward = NULL;
2.29 +
2.30 +class ForwardNativeHelpers :
2.31 + public SMGlobalClass,
2.32 + public IHandleTypeDispatch
2.33 +{
2.34 +public:
2.35 + void OnSourceModAllInitialized()
2.36 + {
2.37 + HandleAccess sec;
2.38 +
2.39 + /* Set GlobalFwd handle access security */
2.40 + g_HandleSys.InitAccessDefaults(NULL, &sec);
2.41 + sec.access[HandleAccess_Read] = 0;
2.42 + sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY | HANDLE_RESTRICT_OWNER;
2.43 +
2.44 + /* Create 'GlobalFwd' handle type */
2.45 + g_GlobalFwdType = g_HandleSys.CreateType("GlobalFwd", this, 0, NULL, &sec, g_pCoreIdent, NULL);
2.46 +
2.47 + /* Private forwards are cloneable */
2.48 + sec.access[HandleAccess_Clone] = 0;
2.49 +
2.50 + /* Create 'PrivateFwd' handle type */
2.51 + g_PrivateFwdType = g_HandleSys.CreateType("PrivateFwd", this, g_GlobalFwdType, NULL, &sec, g_pCoreIdent, NULL);
2.52 + }
2.53 +
2.54 + void OnSourceModShutdown()
2.55 + {
2.56 + g_HandleSys.RemoveType(g_PrivateFwdType, g_pCoreIdent);
2.57 + g_HandleSys.RemoveType(g_GlobalFwdType, g_pCoreIdent);
2.58 + }
2.59 +
2.60 + void OnHandleDestroy(HandleType_t type, void *object)
2.61 + {
2.62 + IForward *pForward = static_cast<IForward *>(object);
2.63 +
2.64 + g_Forwards.ReleaseForward(pForward);
2.65 + }
2.66 +} g_ForwardNativeHelpers;
2.67 +
2.68 +
2.69 +/* Turn a public index into a function ID */
2.70 +inline funcid_t PublicIndexToFuncId(uint32_t idx)
2.71 +{
2.72 + return (idx << 1) | (1 << 0);
2.73 +}
2.74 +
2.75 +/* Reset global function/forward call variables */
2.76 +inline void ResetCall()
2.77 +{
2.78 + s_CallStarted = false;
2.79 + s_pFunction = NULL;
2.80 + s_pCallable = NULL;
2.81 +}
2.82 +
2.83 +static cell_t sm_GetFunctionByName(IPluginContext *pContext, const cell_t *params)
2.84 +{
2.85 + Handle_t hndl = static_cast<Handle_t>(params[1]);
2.86 + HandleError err;
2.87 + char *name;
2.88 + uint32_t idx;
2.89 + IPlugin *pPlugin;
2.90 +
2.91 + if (hndl == 0)
2.92 + {
2.93 + pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
2.94 + } else {
2.95 + pPlugin = g_PluginSys.PluginFromHandle(hndl, &err);
2.96 +
2.97 + if (!pPlugin)
2.98 + {
2.99 + return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", hndl, err);
2.100 + }
2.101 + }
2.102 +
2.103 + pContext->LocalToString(params[2], &name);
2.104 +
2.105 + /* Get public function index */
2.106 + if (pPlugin->GetBaseContext()->FindPublicByName(name, &idx) == SP_ERROR_NOT_FOUND)
2.107 + {
2.108 + /* Return INVALID_FUNCTION if not found */
2.109 + return -1;
2.110 + }
2.111 +
2.112 + /* Return function ID */
2.113 + return PublicIndexToFuncId(idx);
2.114 +}
2.115 +
2.116 +static cell_t sm_CreateGlobalForward(IPluginContext *pContext, const cell_t *params)
2.117 +{
2.118 + cell_t count = params[0];
2.119 + char *name;
2.120 + ParamType forwardParams[SP_MAX_EXEC_PARAMS];
2.121 +
2.122 + if (count - 2 > SP_MAX_EXEC_PARAMS)
2.123 + {
2.124 + return pContext->ThrowNativeErrorEx(SP_ERROR_PARAMS_MAX, NULL);
2.125 + }
2.126 +
2.127 + pContext->LocalToString(params[1], &name);
2.128 +
2.129 + cell_t *addr;
2.130 + for (int i = 3; i <= count; i++)
2.131 + {
2.132 + pContext->LocalToPhysAddr(params[i], &addr);
2.133 + forwardParams[i - 3] = static_cast<ParamType>(*addr);
2.134 + }
2.135 +
2.136 + IForward *pForward = g_Forwards.CreateForward(name, static_cast<ExecType>(params[2]), count - 2, forwardParams);
2.137 +
2.138 + return g_HandleSys.CreateHandle(g_GlobalFwdType, pForward, pContext->GetIdentity(), g_pCoreIdent, NULL);
2.139 +}
2.140 +
2.141 +static cell_t sm_CreateForward(IPluginContext *pContext, const cell_t *params)
2.142 +{
2.143 + cell_t count = params[0];
2.144 + ParamType forwardParams[SP_MAX_EXEC_PARAMS];
2.145 +
2.146 + if (count - 1 > SP_MAX_EXEC_PARAMS)
2.147 + {
2.148 + return pContext->ThrowNativeErrorEx(SP_ERROR_PARAMS_MAX, NULL);
2.149 + }
2.150 +
2.151 + cell_t *addr;
2.152 + for (int i = 2; i <= count; i++)
2.153 + {
2.154 + pContext->LocalToPhysAddr(params[i], &addr);
2.155 + forwardParams[i - 2] = static_cast<ParamType>(*addr);
2.156 + }
2.157 +
2.158 + IChangeableForward *pForward = g_Forwards.CreateForwardEx(NULL, static_cast<ExecType>(params[1]), count - 1, forwardParams);
2.159 +
2.160 + return g_HandleSys.CreateHandle(g_PrivateFwdType, pForward, pContext->GetIdentity(), g_pCoreIdent, NULL);
2.161 +}
2.162 +
2.163 +static cell_t sm_GetForwardFunctionCount(IPluginContext *pContext, const cell_t *params)
2.164 +{
2.165 + Handle_t hndl = static_cast<Handle_t>(params[1]);
2.166 + HandleError err;
2.167 + IForward *pForward;
2.168 +
2.169 + if ((err=g_HandleSys.ReadHandle(hndl, g_GlobalFwdType, NULL, (void **)&pForward))
2.170 + != HandleError_None)
2.171 + {
2.172 + return pContext->ThrowNativeError("Invalid forward handle %x (error %d)", hndl, err);
2.173 + }
2.174 +
2.175 + return pForward->GetFunctionCount();
2.176 +}
2.177 +
2.178 +static cell_t sm_AddToForward(IPluginContext *pContext, const cell_t *params)
2.179 +{
2.180 + Handle_t fwdHandle = static_cast<Handle_t>(params[1]);
2.181 + Handle_t plHandle = static_cast<Handle_t>(params[2]);
2.182 + HandleError err;
2.183 + IChangeableForward *pForward;
2.184 + IPlugin *pPlugin;
2.185 +
2.186 + if ((err=g_HandleSys.ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
2.187 + != HandleError_None)
2.188 + {
2.189 + return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
2.190 + }
2.191 +
2.192 + if (plHandle == 0)
2.193 + {
2.194 + pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
2.195 + } else {
2.196 + pPlugin = g_PluginSys.PluginFromHandle(plHandle, &err);
2.197 +
2.198 + if (!pPlugin)
2.199 + {
2.200 + return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", plHandle, err);
2.201 + }
2.202 + }
2.203 +
2.204 + IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[3]);
2.205 +
2.206 + if (!pFunction)
2.207 + {
2.208 + return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
2.209 + }
2.210 +
2.211 + return pForward->AddFunction(pFunction);
2.212 +}
2.213 +
2.214 +static cell_t sm_RemoveFromForward(IPluginContext *pContext, const cell_t *params)
2.215 +{
2.216 + Handle_t fwdHandle = static_cast<Handle_t>(params[1]);
2.217 + Handle_t plHandle = static_cast<Handle_t>(params[2]);
2.218 + HandleError err;
2.219 + IChangeableForward *pForward;
2.220 + IPlugin *pPlugin;
2.221 +
2.222 + if ((err=g_HandleSys.ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
2.223 + != HandleError_None)
2.224 + {
2.225 + return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
2.226 + }
2.227 +
2.228 + if (plHandle == 0)
2.229 + {
2.230 + pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
2.231 + } else {
2.232 + pPlugin = g_PluginSys.PluginFromHandle(plHandle, &err);
2.233 +
2.234 + if (!pPlugin)
2.235 + {
2.236 + return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", plHandle, err);
2.237 + }
2.238 + }
2.239 +
2.240 + IPluginFunction *pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[3]);
2.241 +
2.242 + if (!pFunction)
2.243 + {
2.244 + return pContext->ThrowNativeError("Invalid function id (%X)", params[3]);
2.245 + }
2.246 +
2.247 + return pForward->RemoveFunction(pFunction);
2.248 +}
2.249 +
2.250 +static cell_t sm_RemoveAllFromForward(IPluginContext *pContext, const cell_t *params)
2.251 +{
2.252 + Handle_t fwdHandle = static_cast<Handle_t>(params[1]);
2.253 + Handle_t plHandle = static_cast<Handle_t>(params[2]);
2.254 + HandleError err;
2.255 + IChangeableForward *pForward;
2.256 + IPlugin *pPlugin;
2.257 +
2.258 + if ((err=g_HandleSys.ReadHandle(fwdHandle, g_PrivateFwdType, NULL, (void **)&pForward))
2.259 + != HandleError_None)
2.260 + {
2.261 + return pContext->ThrowNativeError("Invalid private forward handle %x (error %d)", fwdHandle, err);
2.262 + }
2.263 +
2.264 + if (plHandle == 0)
2.265 + {
2.266 + pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
2.267 + } else {
2.268 + pPlugin = g_PluginSys.PluginFromHandle(plHandle, &err);
2.269 +
2.270 + if (!pPlugin)
2.271 + {
2.272 + return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", plHandle, err);
2.273 + }
2.274 + }
2.275 +
2.276 + return pForward->RemoveFunctionsOfPlugin(pPlugin);
2.277 +}
2.278 +
2.279 +static cell_t sm_CallStartFunction(IPluginContext *pContext, const cell_t *params)
2.280 +{
2.281 + Handle_t hndl;
2.282 + HandleError err;
2.283 + IPlugin *pPlugin;
2.284 +
2.285 + if (s_CallStarted)
2.286 + {
2.287 + return pContext->ThrowNativeError("Cannot start a call while one is already in progress");
2.288 + }
2.289 +
2.290 + hndl = static_cast<Handle_t>(params[1]);
2.291 +
2.292 + if (hndl == 0)
2.293 + {
2.294 + pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
2.295 + } else {
2.296 + pPlugin = g_PluginSys.PluginFromHandle(hndl, &err);
2.297 +
2.298 + if (!pPlugin)
2.299 + {
2.300 + return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", hndl, err);
2.301 + }
2.302 + }
2.303 +
2.304 + s_pFunction = pPlugin->GetBaseContext()->GetFunctionById(params[2]);
2.305 +
2.306 + if (!s_pFunction)
2.307 + {
2.308 + return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
2.309 + }
2.310 +
2.311 + s_pCallable = static_cast<ICallable *>(s_pFunction);
2.312 +
2.313 + s_CallStarted = true;
2.314 +
2.315 + return 1;
2.316 +}
2.317 +
2.318 +static cell_t sm_CallStartForward(IPluginContext *pContext, const cell_t *params)
2.319 +{
2.320 + Handle_t hndl;
2.321 + HandleError err;
2.322 + IForward *pForward;
2.323 +
2.324 + if (s_CallStarted)
2.325 + {
2.326 + return pContext->ThrowNativeError("Cannot start a call while one is already in progress");
2.327 + }
2.328 +
2.329 + hndl = static_cast<Handle_t>(params[1]);
2.330 +
2.331 + if ((err=g_HandleSys.ReadHandle(hndl, g_GlobalFwdType, NULL, (void **)&pForward))
2.332 + != HandleError_None)
2.333 + {
2.334 + return pContext->ThrowNativeError("Invalid forward handle %x (error %d)", hndl, err);
2.335 + }
2.336 +
2.337 + s_pForward = pForward;
2.338 +
2.339 + s_pCallable = static_cast<ICallable *>(pForward);
2.340 +
2.341 + s_CallStarted = true;
2.342 +
2.343 + return 1;
2.344 +}
2.345 +
2.346 +static cell_t sm_CallPushCell(IPluginContext *pContext, const cell_t *params)
2.347 +{
2.348 + int err;
2.349 +
2.350 + if (!s_CallStarted)
2.351 + {
2.352 + return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
2.353 + }
2.354 +
2.355 + err = s_pCallable->PushCell(params[1]);
2.356 +
2.357 + if (err)
2.358 + {
2.359 + s_pCallable->Cancel();
2.360 + ResetCall();
2.361 + return pContext->ThrowNativeErrorEx(err, NULL);
2.362 + }
2.363 +
2.364 + return 1;
2.365 +}
2.366 +
2.367 +static cell_t sm_CallPushCellRef(IPluginContext *pContext, const cell_t *params)
2.368 +{
2.369 + int err;
2.370 + cell_t *addr;
2.371 +
2.372 + if (!s_CallStarted)
2.373 + {
2.374 + return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
2.375 + }
2.376 +
2.377 + pContext->LocalToPhysAddr(params[1], &addr);
2.378 +
2.379 + err = s_pCallable->PushCellByRef(addr);
2.380 +
2.381 + if (err)
2.382 + {
2.383 + s_pCallable->Cancel();
2.384 + ResetCall();
2.385 + return pContext->ThrowNativeErrorEx(err, NULL);
2.386 + }
2.387 +
2.388 + return 1;
2.389 +}
2.390 +
2.391 +static cell_t sm_CallPushFloat(IPluginContext *pContext, const cell_t *params)
2.392 +{
2.393 + int err;
2.394 +
2.395 + if (!s_CallStarted)
2.396 + {
2.397 + return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
2.398 + }
2.399 +
2.400 + err = s_pCallable->PushFloat(sp_ctof(params[1]));
2.401 +
2.402 + if (err)
2.403 + {
2.404 + s_pCallable->Cancel();
2.405 + ResetCall();
2.406 + return pContext->ThrowNativeErrorEx(err, NULL);
2.407 + }
2.408 +
2.409 + return 1;
2.410 +}
2.411 +
2.412 +static cell_t sm_CallPushFloatRef(IPluginContext *pContext, const cell_t *params)
2.413 +{
2.414 + int err;
2.415 + cell_t *addr;
2.416 +
2.417 + if (!s_CallStarted)
2.418 + {
2.419 + return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
2.420 + }
2.421 +
2.422 + pContext->LocalToPhysAddr(params[1], &addr);
2.423 +
2.424 + err = s_pCallable->PushFloatByRef(reinterpret_cast<float *>(addr));
2.425 +
2.426 + if (err)
2.427 + {
2.428 + s_pCallable->Cancel();
2.429 + ResetCall();
2.430 + return pContext->ThrowNativeErrorEx(err, NULL);
2.431 + }
2.432 +
2.433 + return 1;
2.434 +}
2.435 +
2.436 +static cell_t sm_CallPushArray(IPluginContext *pContext, const cell_t *params)
2.437 +{
2.438 + int err;
2.439 + cell_t *addr;
2.440 +
2.441 + if (!s_CallStarted)
2.442 + {
2.443 + return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
2.444 + }
2.445 +
2.446 + pContext->LocalToPhysAddr(params[1], &addr);
2.447 +
2.448 + err = s_pCallable->PushArray(addr, params[2], NULL);
2.449 +
2.450 + if (err)
2.451 + {
2.452 + s_pCallable->Cancel();
2.453 + ResetCall();
2.454 + return pContext->ThrowNativeErrorEx(err, NULL);
2.455 + }
2.456 +
2.457 + return 1;
2.458 +}
2.459 +
2.460 +static cell_t sm_CallPushArrayEx(IPluginContext *pContext, const cell_t *params)
2.461 +{
2.462 + int err;
2.463 + cell_t *addr;
2.464 +
2.465 + if (!s_CallStarted)
2.466 + {
2.467 + return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
2.468 + }
2.469 +
2.470 + pContext->LocalToPhysAddr(params[1], &addr);
2.471 +
2.472 + err = s_pCallable->PushArray(addr, params[2], params[3]);
2.473 +
2.474 + if (err)
2.475 + {
2.476 + s_pCallable->Cancel();
2.477 + ResetCall();
2.478 + return pContext->ThrowNativeErrorEx(err, NULL);
2.479 + }
2.480 +
2.481 + return 1;
2.482 +}
2.483 +
2.484 +static cell_t sm_CallPushString(IPluginContext *pContext, const cell_t *params)
2.485 +{
2.486 + int err;
2.487 + char *value;
2.488 +
2.489 + if (!s_CallStarted)
2.490 + {
2.491 + return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
2.492 + }
2.493 +
2.494 + pContext->LocalToString(params[1], &value);
2.495 +
2.496 + err = s_pCallable->PushString(value);
2.497 +
2.498 + if (err)
2.499 + {
2.500 + s_pCallable->Cancel();
2.501 + ResetCall();
2.502 + return pContext->ThrowNativeErrorEx(err, NULL);
2.503 + }
2.504 +
2.505 + return 1;
2.506 +}
2.507 +
2.508 +static cell_t sm_CallPushStringEx(IPluginContext *pContext, const cell_t *params)
2.509 +{
2.510 + int err;
2.511 + char *value;
2.512 +
2.513 + if (!s_CallStarted)
2.514 + {
2.515 + return pContext->ThrowNativeError("Cannot push parameters when there is no call in progress");
2.516 + }
2.517 +
2.518 + pContext->LocalToString(params[1], &value);
2.519 +
2.520 + err = s_pCallable->PushStringEx(value, params[2], params[3], params[4]);
2.521 +
2.522 + if (err)
2.523 + {
2.524 + s_pCallable->Cancel();
2.525 + ResetCall();
2.526 + return pContext->ThrowNativeErrorEx(err, NULL);
2.527 + }
2.528 +
2.529 + return 1;
2.530 +}
2.531 +
2.532 +static cell_t sm_CallFinish(IPluginContext *pContext, const cell_t *params)
2.533 +{
2.534 + int err;
2.535 + cell_t *result;
2.536 +
2.537 + if (!s_CallStarted)
2.538 + {
2.539 + return pContext->ThrowNativeError("Cannot finish call when there is no call in progress");
2.540 + }
2.541 +
2.542 + pContext->LocalToPhysAddr(params[1], &result);
2.543 +
2.544 + if (s_pFunction)
2.545 + {
2.546 + IPluginFunction *pFunction = s_pFunction;
2.547 + err = pFunction->Execute(result);
2.548 + } else if (s_pForward) {
2.549 + IForward *pForward = s_pForward;
2.550 + err = pForward->Execute(result, NULL);
2.551 + }
2.552 +
2.553 + ResetCall();
2.554 +
2.555 + return err;
2.556 +}
2.557 +
2.558 +static cell_t sm_CallCancel(IPluginContext *pContext, const cell_t *params)
2.559 +{
2.560 + if (!s_CallStarted)
2.561 + {
2.562 + return pContext->ThrowNativeError("Cannot cancel call when there is no call in progress");
2.563 + }
2.564 +
2.565 + s_pCallable->Cancel();
2.566 + ResetCall();
2.567 +
2.568 + return 1;
2.569 +}
2.570 +
2.571 +REGISTER_NATIVES(functionNatives)
2.572 +{
2.573 + {"GetFunctionByName", sm_GetFunctionByName},
2.574 + {"CreateGlobalForward", sm_CreateGlobalForward},
2.575 + {"CreateForward", sm_CreateForward},
2.576 + {"GetForwardFunctionCount", sm_GetForwardFunctionCount},
2.577 + {"AddToForward", sm_AddToForward},
2.578 + {"RemoveFromForward", sm_RemoveFromForward},
2.579 + {"RemoveAllFromForward", sm_RemoveAllFromForward},
2.580 + {"Call_StartFunction", sm_CallStartFunction},
2.581 + {"Call_StartForward", sm_CallStartForward},
2.582 + {"Call_PushCell", sm_CallPushCell},
2.583 + {"Call_PushCellRef", sm_CallPushCellRef},
2.584 + {"Call_PushFloat", sm_CallPushFloat},
2.585 + {"Call_PushFloatRef", sm_CallPushFloatRef},
2.586 + {"Call_PushArray", sm_CallPushArray},
2.587 + {"Call_PushArrayEx", sm_CallPushArrayEx},
2.588 + {"Call_PushString", sm_CallPushString},
2.589 + {"Call_PushStringEx", sm_CallPushStringEx},
2.590 + {"Call_Finish", sm_CallFinish},
2.591 + {"Call_Cancel", sm_CallCancel},
2.592 + {NULL, NULL},
2.593 +};
3.1 --- a/core/systems/ForwardSys.cpp Thu Mar 15 22:32:45 2007 +0000
3.2 +++ b/core/systems/ForwardSys.cpp Fri Mar 16 06:54:24 2007 +0000
3.3 @@ -601,6 +601,18 @@
3.4 return AddFunction(pFunc);
3.5 }
3.6
3.7 +bool CForward::RemoveFunction(IPluginContext *pContext, funcid_t index)
3.8 +{
3.9 + IPluginFunction *pFunc = pContext->GetFunctionById(index);
3.10 +
3.11 + if (!pFunc)
3.12 + {
3.13 + return false;
3.14 + }
3.15 +
3.16 + return RemoveFunction(pFunc);
3.17 +}
3.18 +
3.19 bool CForward::RemoveFunction(IPluginFunction *func)
3.20 {
3.21 bool found = false;
4.1 --- a/core/systems/ForwardSys.h Thu Mar 15 22:32:45 2007 +0000
4.2 +++ b/core/systems/ForwardSys.h Fri Mar 16 06:54:24 2007 +0000
4.3 @@ -64,6 +64,7 @@
4.4 virtual unsigned int RemoveFunctionsOfPlugin(IPlugin *plugin);
4.5 virtual bool AddFunction(IPluginFunction *func);
4.6 virtual bool AddFunction(IPluginContext *ctx, funcid_t index);
4.7 + virtual bool RemoveFunction(IPluginContext *ctx, funcid_t index);
4.8 public:
4.9 static CForward *CreateForward(const char *name,
4.10 ExecType et,
5.1 --- a/core/vm/sp_vm_function.cpp Thu Mar 15 22:32:45 2007 +0000
5.2 +++ b/core/vm/sp_vm_function.cpp Fri Mar 16 06:54:24 2007 +0000
5.3 @@ -81,11 +81,6 @@
5.4
5.5 int CFunction::PushCellByRef(cell_t *cell, int flags)
5.6 {
5.7 - if (m_curparam >= SP_MAX_EXEC_PARAMS)
5.8 - {
5.9 - return SetError(SP_ERROR_PARAMS_MAX);
5.10 - }
5.11 -
5.12 return PushArray(cell, 1, flags);
5.13 }
5.14
6.1 --- a/plugins/include/clients.inc Thu Mar 15 22:32:45 2007 +0000
6.2 +++ b/plugins/include/clients.inc Fri Mar 16 06:54:24 2007 +0000
6.3 @@ -272,4 +272,4 @@
6.4 * @error Invalid client index, client not connected,
6.5 * or client not a fake client.
6.6 */
6.7 -native SetFakeClientConVar(client, const String:cvar[], const String:value[]);
6.8 \ No newline at end of file
6.9 +native SetFakeClientConVar(client, const String:cvar[], const String:value[]);
7.1 --- a/plugins/include/console.inc Thu Mar 15 22:32:45 2007 +0000
7.2 +++ b/plugins/include/console.inc Fri Mar 16 06:54:24 2007 +0000
7.3 @@ -91,7 +91,7 @@
7.4 * @noreturn
7.5 * @error Invalid client index, or client not connected.
7.6 */
7.7 -native ClientCommand(client, const String:fmt[], {String,Float,Handle,_}:...);
7.8 +native ClientCommand(client, const String:fmt[], {String,Float,Handle,Function,_}:...);
7.9
7.10 /**
7.11 * Sends a message to the server console.
7.12 @@ -100,7 +100,7 @@
7.13 * @param ... Variable number of format parameters.
7.14 * @noreturn
7.15 */
7.16 -native PrintToServer(const String:format[], {Handle,Float,String,_}:...);
7.17 +native PrintToServer(const String:format[], {Handle,Float,String,Function,_}:...);
7.18
7.19 /**
7.20 * Sends a message to a client's console.
7.21 @@ -111,7 +111,7 @@
7.22 * @noreturn
7.23 * @error If the client is not connected an error will be thrown.
7.24 */
7.25 -native PrintToConsole(client, const String:format[], {Handle,Float,String,_}:...);
7.26 +native PrintToConsole(client, const String:format[], {Handle,Float,String,Function,_}:...);
7.27
7.28 /**
7.29 * Called when a server-only command is invoked.
8.1 --- a/plugins/include/core.inc Thu Mar 15 22:32:45 2007 +0000
8.2 +++ b/plugins/include/core.inc Fri Mar 16 06:54:24 2007 +0000
8.3 @@ -28,6 +28,14 @@
8.4 };
8.5
8.6 /**
8.7 + * Function helper values
8.8 + */
8.9 +enum Function
8.10 +{
8.11 + INVALID_FUNCTION = -1,
8.12 +};
8.13 +
8.14 +/**
8.15 * Specifies what to do after a hook completes.
8.16 */
8.17 enum Action
9.1 --- a/plugins/include/files.inc Thu Mar 15 22:32:45 2007 +0000
9.2 +++ b/plugins/include/files.inc Fri Mar 16 06:54:24 2007 +0000
9.3 @@ -54,7 +54,7 @@
9.4 * @param ... Format arguments.
9.5 * @return Number of bytes written to buffer (not including null terminator).
9.6 */
9.7 -native BuildPath(PathType:type, String:buffer[], maxlength, const String:fmt[], ...);
9.8 +native BuildPath(PathType:type, String:buffer[], maxlength, const String:fmt[], {Handle,Float,String,Function,_}:...);
9.9
9.10 /**
9.11 * @brief Opens a directory/folder for contents enumeration.
9.12 @@ -186,4 +186,4 @@
9.13 * @param ... Variable number of format parameters.
9.14 * @return True on success, false otherwise.
9.15 */
9.16 -native bool:WriteFileLine(Handle:hndl, const String:format[], {Handle,Float,String,_}:...);
9.17 +native bool:WriteFileLine(Handle:hndl, const String:format[], {Handle,Float,String,Function,_}:...);
10.1 --- a/plugins/include/functions.inc Thu Mar 15 22:32:45 2007 +0000
10.2 +++ b/plugins/include/functions.inc Fri Mar 16 06:54:24 2007 +0000
10.3 @@ -13,6 +13,48 @@
10.4 * Version: $Id$
10.5 */
10.6
10.7 +#define SP_PARAMFLAG_BYREF (1<<0) /**< Internal use only. */
10.8 +
10.9 +/**
10.10 + * Describes the various ways to pass parameters to functions or forwards.
10.11 + */
10.12 +enum ParamType
10.13 +{
10.14 + Param_Any = 0, /**< Any data type can be pushed */
10.15 + Param_Cell = (1<<1), /**< Only basic cells can be pushed */
10.16 + Param_Float = (2<<1), /**< Only floats can be pushed */
10.17 + Param_String = (3<<1)|SP_PARAMFLAG_BYREF, /**< Only strings can be pushed */
10.18 + Param_Array = (4<<1)|SP_PARAMFLAG_BYREF, /**< Only arrays can be pushed */
10.19 + Param_VarArgs = (5<<1), /**< Same as "..." in plugins, anything can be pushed, but it will always be byref */
10.20 + Param_CellByRef = (1<<1)|SP_PARAMFLAG_BYREF, /**< Only a cell by reference can be pushed */
10.21 + Param_FloatByRef = (2<<1)|SP_PARAMFLAG_BYREF /**< Only a float by reference can be pushed */
10.22 +};
10.23 +
10.24 +/**
10.25 + * Defines how a forward iterates through plugin functions.
10.26 + */
10.27 +enum ExecType
10.28 +{
10.29 + ET_Ignore = 0, /**< Ignore all return values, return 0 */
10.30 + ET_Single = 1, /**< Only return the last exec, ignore all others */
10.31 + ET_Event = 2, /**< Acts as an event with the Actions defined in core.inc, no mid-Stops allowed, returns highest */
10.32 + ET_Hook = 3 /**< Acts as a hook with the Actions defined in core.inc, mid-Stops allowed, returns highest */
10.33 +};
10.34 +
10.35 +/**
10.36 + * @section Flags that are used with Call_PushArrayEx() and Call_PushStringEx()
10.37 + */
10.38 +#define SM_PARAM_COPYBACK (1<<0) /**< Copy an array/reference back after call */
10.39 +#define SM_PARAM_STRING_UTF8 (1<<0) /**< String should be UTF-8 handled */
10.40 +#define SM_PARAM_STRING_COPY (1<<1) /**< String should be copied into the plugin */
10.41 +
10.42 +/**
10.43 + * @endsection
10.44 + */
10.45 +
10.46 +/**
10.47 + * @section Error codes
10.48 + */
10.49 #define SP_ERROR_NONE 0 /**< No error occurred */
10.50 #define SP_ERROR_FILE_FORMAT 1 /**< File format unrecognized */
10.51 #define SP_ERROR_DECOMPRESSOR 2 /**< A decompressor was not found */
10.52 @@ -41,6 +83,243 @@
10.53 #define SP_ERROR_ABORTED 25 /**< Function call was aborted */
10.54
10.55 /**
10.56 + * @endsection
10.57 + */
10.58 +
10.59 +/**
10.60 + * Gets a function id from a function name.
10.61 + *
10.62 + * @param plugin Handle of the plugin that contains the function.
10.63 + Pass INVALID_HANDLE to search in the calling plugin.
10.64 + * @param name Name of the function.
10.65 + * @return Function id or INVALID_FUNCTION if not found.
10.66 + * @error Invalid or corrupt plugin handle.
10.67 + */
10.68 +native Function:GetFunctionByName(Handle:plugin, const String:name[]);
10.69 +
10.70 +/**
10.71 + * Creates a global forward.
10.72 + *
10.73 + * @note The name used to create the forward is used as its public function in all target plugins.
10.74 + * @note This is ideal for global, static forwards that are never changed.
10.75 + *
10.76 + * @param name Name of public function to use in forward.
10.77 + * @param type Execution type to be used.
10.78 + * @param ... Variable number of parameter types (up to 32).
10.79 + * @return Handle to new global forward.
10.80 + * @error More than 32 paramater types passed.
10.81 + */
10.82 +native Handle:CreateGlobalForward(const String:name[], ExecType:type, {ParamType}:...);
10.83 +
10.84 +/**
10.85 + * Creates a private forward.
10.86 + *
10.87 + * @note No functions are automatically added. Use AddToForward() to do this.
10.88 + *
10.89 + * @param type Execution type to be used.
10.90 + * @param ... Variable number of parameter types (up to 32).
10.91 + * @return Handle to new private forward.
10.92 + * @error More than 32 paramater types passed.
10.93 + */
10.94 +native Handle:CreateForward(ExecType:type, {ParamType}:...);
10.95 +
10.96 +/**
10.97 + * Returns the number of functions in a global or private forward's call list.
10.98 + *
10.99 + * @param fwd Handle to global or private forward.
10.100 + * @return Number of functions in forward.
10.101 + * @error Invalid or corrupt forward handle.
10.102 + */
10.103 +native GetForwardFunctionCount(Handle:fwd);
10.104 +
10.105 +/**
10.106 + * Adds a function to a private forward's call list.
10.107 + *
10.108 + * @note Cannot be used during an incompleted call.
10.109 + *
10.110 + * @param fwd Handle to private forward.
10.111 + * @param plugin Handle of the plugin that contains the function.
10.112 + * Pass INVALID_HANDLE to specify the calling plugin.
10.113 + * @param func Function to add to forward.
10.114 + * @return True on success, false otherwise.
10.115 + * @error Invalid or corrupt private forward handle, invalid or corrupt plugin handle, or invalid function.
10.116 + */
10.117 +native bool:AddToForward(Handle:fwd, Handle:plugin, Function:func);
10.118 +
10.119 +/**
10.120 + * Removes a function from a private forward's call list.
10.121 + *
10.122 + * @note Only removes one instance.
10.123 + * @note Functions will be removed automatically if their parent plugin is unloaded.
10.124 + *
10.125 + * @param fwd Handle to private forward.
10.126 + * @param plugin Handle of the plugin that contains the function.
10.127 + * Pass INVALID_HANDLE to specify the calling plugin.
10.128 + * @param func Function to remove from forward.
10.129 + * @return True on success, false otherwise.
10.130 + * @error Invalid or corrupt private forward handle, invalid or corrupt plugin handle, or invalid function.
10.131 + */
10.132 +native bool:RemoveFromForward(Handle:fwd, Handle:plugin, Function:func);
10.133 +
10.134 +/**
10.135 + * Removes all instances of a plugin from a private forward's call list.
10.136 + *
10.137 + * @note Functions will be removed automatically if their parent plugin is unloaded.
10.138 + *
10.139 + * @param fwd Handle to private forward.
10.140 + * @param plugin Handle of the plugin to remove instances of.
10.141 + * Pass INVALID_HANDLE to specify the calling plugin.
10.142 + * @return Number of functions removed from forward.
10.143 + * @error Invalid or corrupt private forward handle or invalid or corrupt plugin handle.
10.144 + */
10.145 +native RemoveAllFromForward(Handle:fwd, Handle:plugin);
10.146 +
10.147 +/**
10.148 + * Starts a call to functions in a forward's call list.
10.149 + *
10.150 + * @note Cannot be used during an incompleted call.
10.151 + *
10.152 + * @param fwd Handle to global or private forward.
10.153 + * @noreturn
10.154 + * @error Invalid or corrupt forward handle or called before another call has completed.
10.155 + */
10.156 +native Call_StartForward(Handle:fwd);
10.157 +
10.158 +/**
10.159 + * Starts a call to a function.
10.160 + *
10.161 + * @note Cannot be used during an incompleted call.
10.162 + *
10.163 + * @param plugin Handle of the plugin that contains the function.
10.164 + * Pass INVALID_HANDLE to specify the calling plugin.
10.165 + * @param func Function to call.
10.166 + * @noreturn
10.167 + * @error Invalid or corrupt plugin handle, invalid function, or called before another call has completed.
10.168 + */
10.169 +native Call_StartFunction(Handle:plugin, Function:func);
10.170 +
10.171 +/**
10.172 + * Pushes a cell onto the current call.
10.173 + *
10.174 + * @note Cannot be used before a call has been started.
10.175 + *
10.176 + * @param value Cell value to push.
10.177 + * @noreturn
10.178 + * @error Called before a call has been started.
10.179 + */
10.180 +native Call_PushCell({Handle,Function,_}:value);
10.181 +
10.182 +/**
10.183 + * Pushes a cell by reference onto the current call.
10.184 + *
10.185 + * @note Cannot be used before a call has been started.
10.186 + *
10.187 + * @param value Cell reference to push.
10.188 + * @noreturn
10.189 + * @error Called before a call has been started.
10.190 + */
10.191 +native Call_PushCellRef(&{Handle,Function,_}:value);
10.192 +
10.193 +
10.194 +/**
10.195 + * Pushes a float onto the current call.
10.196 + *
10.197 + * @note Cannot be used before a call has been started.
10.198 + *
10.199 + * @param value Floating point value to push.
10.200 + * @noreturn
10.201 + * @error Called before a call has been started.
10.202 + */
10.203 +native Call_PushFloat(Float:value);
10.204 +
10.205 +/**
10.206 + * Pushes a float by reference onto the current call.
10.207 + *
10.208 + * @note Cannot be used before a call has been started.
10.209 + *
10.210 + * @param value Floating point reference to push.
10.211 + * @noreturn
10.212 + * @error Called before a call has been started.
10.213 + */
10.214 +native Call_PushFloatRef(&Float:value);
10.215 +
10.216 +/**
10.217 + * Pushes an array onto the current call.
10.218 + *
10.219 + * @note Changes to array are not copied back to caller. Use PushArrayEx() to do this.
10.220 + * @note Cannot be used before a call has been started.
10.221 + *
10.222 + * @param value Array to push.
10.223 + * @param size Size of array.
10.224 + * @noreturn
10.225 + * @error Called before a call has been started.
10.226 + */
10.227 +native Call_PushArray(const {Handle,Float,Function,_}:value[], size);
10.228 +
10.229 +/**
10.230 + * Pushes an array onto the current call.
10.231 + *
10.232 + * @note Cannot be used before a call has been started.
10.233 + *
10.234 + * @param value Array to push.
10.235 + * @param size Size of array.
10.236 + * @param cpflags Whether or not changes should be copied back to the input array.
10.237 + * See SP_PARAM_* constants for details.
10.238 + * @noreturn
10.239 + * @error Called before a call has been started.
10.240 + */
10.241 +native Call_PushArrayEx({Handle,Float,Function,_}:value[], size, cpflags);
10.242 +
10.243 +/**
10.244 + * Pushes a string onto the current call.
10.245 + *
10.246 + * @note Changes to string are not copied back to caller. Use PushStringEx() to do this.
10.247 + * @note Cannot be used before a call has been started.
10.248 + *
10.249 + * @param value String to push.
10.250 + * @noreturn
10.251 + * @error Called before a call has been started.
10.252 + */
10.253 +native Call_PushString(const String:value[]);
10.254 +
10.255 +/**
10.256 + * Pushes a string onto the current call.
10.257 + *
10.258 + * @note Cannot be used before a call has been started.
10.259 + *
10.260 + * @param value String to push.
10.261 + * @param length Length of string buffer.
10.262 + * @param szflags Flags determining how string should be handled.
10.263 + * See SP_PARAM_STRING_* constants for details.
10.264 + * @param cpflags Whether or not changes should be copied back to the input array.
10.265 + * See SP_PARAM_* constants for details.
10.266 + * @noreturn
10.267 + * @error Called before a call has been started.
10.268 + */
10.269 +native Call_PushStringEx(String:value[], length, szflags, cpflags);
10.270 +
10.271 +/**
10.272 + * Completes a call to a function or forward's call list.
10.273 + *
10.274 + * @note Cannot be used before a call has been started.
10.275 + *
10.276 + * @param result Return value of function or forward's call list.
10.277 + * @return SP_ERROR_NONE on success, any other integer on failure.
10.278 + * @error Called before a call has been started.
10.279 + */
10.280 +native Call_Finish(&result);
10.281 +
10.282 +/**
10.283 + * Cancels a call to a function or forward's call list.
10.284 + *
10.285 + * @note Cannot be used before a call has been started.
10.286 + *
10.287 + * @noreturn
10.288 + * @error Called before a call has been started.
10.289 + */
10.290 +native Call_Cancel();
10.291 +
10.292 +/**
10.293 * Defines a native function.
10.294 *
10.295 * It is not necessary to validate the parameter count
10.296 @@ -69,7 +348,7 @@
10.297 * @param fmt Error message format.
10.298 * @param ... Format arguments.
10.299 */
10.300 -native ThrowNativeError(error, const String:fmt[], {Handle,Float,String,_}:...);
10.301 +native ThrowNativeError(error, const String:fmt[], {Handle,Float,String,Function,_}:...);
10.302
10.303 /**
10.304 * Retrieves the string length from a native parameter string. This is useful
10.305 @@ -78,7 +357,7 @@
10.306 *
10.307 * @param param Parameter number, starting from 1.
10.308 * @param length Stores the length of the string.
10.309 - * @return SP_ERROR_NONE on sucecss, any other integer on failure.
10.310 + * @return SP_ERROR_NONE on success, any other integer on failure.
10.311 * @error Invalid parameter number or calling from a non-native function.
10.312 */
10.313 native GetNativeStringLength(param, &length);
10.314 @@ -137,7 +416,7 @@
10.315 * @noreturn
10.316 * @error Invalid parameter number or calling from a non-native function.
10.317 */
10.318 -native SetNativeCellRef(param, {Float,Handle,_}:value);
10.319 +native SetNativeCellRef(param, {Float,Function,Handle,_}:value);
10.320
10.321 /**
10.322 * Gets an array from a native parameter (always by reference).
10.323 @@ -148,7 +427,7 @@
10.324 * @return SP_ERROR_NONE on success, anything else on failure.
10.325 * @error Invalid parameter number or calling from a non-native function.
10.326 */
10.327 -native GetNativeArray(param, {Float,Handle,_}:local[], size);
10.328 +native GetNativeArray(param, {Float,Function,Handle,_}:local[], size);
10.329
10.330 /**
10.331 * Copies a local array into a native parameter array (always by reference).
10.332 @@ -159,7 +438,7 @@
10.333 * @return SP_ERROR_NONE on success, anything else on failure.
10.334 * @error Invalid parameter number or calling from a non-native function.
10.335 */
10.336 -native SetNativeArray(param, const {Float,Handle,_}:local[], size);
10.337 +native SetNativeArray(param, const {Float,Function,Handle,_}:local[], size);
10.338
10.339 /**
10.340 * Formats a string using parameters from a native.
11.1 --- a/plugins/include/helpers.inc Thu Mar 15 22:32:45 2007 +0000
11.2 +++ b/plugins/include/helpers.inc Fri Mar 16 06:54:24 2007 +0000
11.3 @@ -44,3 +44,30 @@
11.4
11.5 Format(buffer, maxlength, "\"%s<%d><%s><>\"", name, userid, auth);
11.6 }
11.7 +
11.8 +/**
11.9 + * Returns plugin handle from plugin filename.
11.10 + *
11.11 + * @param filename Filename of the plugin to search for.
11.12 + * @Returns Handle to plugin if found, INVALID_HANDLE otherwise.
11.13 + */
11.14 +stock Handle:FindPluginByFile(const String:filename[])
11.15 +{
11.16 + decl String:buffer[256];
11.17 +
11.18 + new Handle:iter = GetPluginIterator();
11.19 + new Handle:pl;
11.20 +
11.21 + while (MorePlugins(iter))
11.22 + {
11.23 + pl = ReadPlugin(iter);
11.24 +
11.25 + GetPluginFilename(pl, buffer, sizeof(buffer));
11.26 + if (StrCompare(buffer, filename) == 0)
11.27 + {
11.28 + return pl;
11.29 + }
11.30 + }
11.31 +
11.32 + return INVALID_HANDLE;
11.33 +}
12.1 --- a/plugins/include/sourcemod.inc Thu Mar 15 22:32:45 2007 +0000
12.2 +++ b/plugins/include/sourcemod.inc Fri Mar 16 06:54:24 2007 +0000
12.3 @@ -189,7 +189,7 @@
12.4 * @noreturn
12.5 * @error Always!
12.6 */
12.7 -native ThrowError(const String:fmt[], {Handle,Float,String,_}:...);
12.8 +native ThrowError(const String:fmt[], {Handle,Float,String,Function,_}:...);
12.9
12.10 /**
12.11 * Logs a generic message to the HL2 logs.
12.12 @@ -198,7 +198,7 @@
12.13 * @param ... Format arguments.
12.14 * @noreturn
12.15 */
12.16 -native LogToGame(const String:format[], {Handle,Float,String,_}:...);
12.17 +native LogToGame(const String:format[], {Handle,Float,String,Function,_}:...);
12.18
12.19 /**
12.20 * Logs a plugin message to the SourceMod logs.
12.21 @@ -207,7 +207,7 @@
12.22 * @param ... Format arguments.
12.23 * @noreturn
12.24 */
12.25 -native LogMessage(const String:format[], {Handle,Float,String,_}:...);
12.26 +native LogMessage(const String:format[], {Handle,Float,String,Function,_}:...);
12.27
12.28 /**
12.29 * Logs a plugin error message to the SourceMod logs.
12.30 @@ -216,7 +216,7 @@
12.31 * @param ... Format arguments.
12.32 * @noreturn
12.33 */
12.34 -native LogError(const String:format[], {Handle,Float,String,_}:...);
12.35 +native LogError(const String:format[], {Handle,Float,String,Function,_}:...);
12.36
12.37 /**
12.38 * Gets the system time as a unix timestamp.
13.1 --- a/plugins/include/string.inc Thu Mar 15 22:32:45 2007 +0000
13.2 +++ b/plugins/include/string.inc Fri Mar 16 06:54:24 2007 +0000
13.3 @@ -93,7 +93,7 @@
13.4 * @param ... Variable number of format parameters.
13.5 * @return Number of cells written.
13.6 */
13.7 -native Format(String:buffer[], maxlength, const String:format[], {Handle,Float,String,_}:...);
13.8 +native Format(String:buffer[], maxlength, const String:format[], {Handle,Float,String,Function,_}:...);
13.9
13.10 /**
13.11 * Formats a string according to the SourceMod format rules (see documentation).
13.12 @@ -106,7 +106,7 @@
13.13 * @param ... Variable number of format parameters.
13.14 * @return Number of cells written.
13.15 */
13.16 -native FormatEx(String:buffer[], maxlength, const String:format[], {Handle,Float,String,_}:...);
13.17 +native FormatEx(String:buffer[], maxlength, const String:format[], {Handle,Float,String,Function,_}:...);
13.18
13.19 /**
13.20 * Formats a string according to the SourceMod format rules (see documentation).
14.1 --- a/plugins/include/usermessages.inc Thu Mar 15 22:32:45 2007 +0000
14.2 +++ b/plugins/include/usermessages.inc Fri Mar 16 06:54:24 2007 +0000
14.3 @@ -57,11 +57,12 @@
14.4 * @param msgname Message name to start.
14.5 * @param clients Array containing player indexes to broadcast to.
14.6 * @param numClients Number of players in the array.
14.7 + * @param flags Optional flags to set.
14.8 * @return A handle to a bf_write bit packing structure, or
14.9 * INVALID_HANDLE on failure.
14.10 * @error Invalid message name or unable to start a message.
14.11 */
14.12 -native Handle:StartMessage(String:msgname[], clients[], numClients, flags);
14.13 +native Handle:StartMessage(String:msgname[], clients[], numClients, flags=0);
14.14
14.15 /**
14.16 * Starts a usermessage (network message).
14.17 @@ -71,11 +72,12 @@
14.18 * @param msg Message index to start.
14.19 * @param clients Array containing player indexes to broadcast to.
14.20 * @param numClients Number of players in the array.
14.21 + * @param flags Optional flags to set.
14.22 * @return A handle to a bf_write bit packing structure, or
14.23 * INVALID_HANDLE on failure.
14.24 * @error Invalid message name or unable to start a message.
14.25 */
14.26 -native Handle:StartMessageEx(UserMsg:msg, clients[], numClients, flags);
14.27 +native Handle:StartMessageEx(UserMsg:msg, clients[], numClients, flags=0);
14.28
14.29 /**
14.30 * Ends a previously started user message (network message).
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/plugins/testsuite/callfunctest.sp Fri Mar 16 06:54:24 2007 +0000
15.3 @@ -0,0 +1,104 @@
15.4 +#include <sourcemod>
15.5 +
15.6 +public Plugin:myinfo =
15.7 +{
15.8 + name = "Function Call Testing Lab",
15.9 + author = "AlliedModders LLC",
15.10 + description = "Tests basic function calls",
15.11 + version = "1.0.0.0",
15.12 + url = "http://www.sourcemod.net/"
15.13 +};
15.14 +
15.15 +public OnPluginStart()
15.16 +{
15.17 + RegServerCmd("test_callfunc", Command_CallFunc);
15.18 +}
15.19 +
15.20 +public OnCallFuncReceived(num, Float:fnum, String:str[], String:str2[], &val, &Float:fval, array[], array2[], size, hello2[1])
15.21 +{
15.22 + PrintToServer("Inside OnCallFuncReceived...");
15.23 +
15.24 + PrintToServer("num = %d (expected: %d)", num, 5);
15.25 + PrintToServer("fnum = %f (expected: %f)", fnum, 7.17);
15.26 + PrintToServer("str[] = \"%s\" (expected: \"%s\")", str, "Gaben");
15.27 + PrintToServer("str2[] = \"%s\" (expected: \"%s\")", str2, ".taf si nebaG");
15.28 +
15.29 + PrintToServer("val = %d (expected %d, setting to %d)", val, 62, 15);
15.30 + val = 15;
15.31 +
15.32 + PrintToServer("fval = %f (expected: %f, setting to %f)", fval, 6.25, 1.5);
15.33 + fval = 1.5;
15.34 +
15.35 + PrintToServer("Printing %d elements of array[] (expected: %d)", size, 6);
15.36 + for (new i = 0; i < size; i++)
15.37 + {
15.38 + PrintToServer("array[%d] = %d (expected: %d)", i, array[i], i);
15.39 + }
15.40 + for (new i = 0; i < size; i++)
15.41 + {
15.42 + PrintToServer("array2[%d] = %d (expected: %d)", i, array[i], i);
15.43 + }
15.44 +
15.45 + /* This shouldn't get copied back */
15.46 + StrCopy(str, strlen(str) + 1, "Yeti");
15.47 + /* This should get copied back */
15.48 + StrCopy(str2, strlen(str2) + 1, "Gaben is fat.");
15.49 +
15.50 + /* This should get copied back */
15.51 + array[0] = 5;
15.52 + array[1] = 6;
15.53 + /* This shouldn't get copied back */
15.54 + hello2[0] = 25;
15.55 +
15.56 + return 42;
15.57 +}
15.58 +
15.59 +public Action:Command_CallFunc(args)
15.60 +{
15.61 + new a = 62;
15.62 + new Float:b = 6.25;
15.63 + new const String:what[] = "Gaben";
15.64 + new String:truth[] = ".taf si nebaG";
15.65 + new hello[] = {0, 1, 2, 3, 4, 5};
15.66 + new hello2[] = {9};
15.67 + new pm = 6;
15.68 + new err;
15.69 + new ret;
15.70 +
15.71 + new Function:func = GetFunctionByName(INVALID_HANDLE, "OnCallFuncReceived");
15.72 +
15.73 + if (func == INVALID_FUNCTION)
15.74 + {
15.75 + PrintToServer("Failed to get the function id of OnCallFuncReceived");
15.76 + return Plugin_Handled;
15.77 + }
15.78 +
15.79 + PrintToServer("Calling OnCallFuncReceived...");
15.80 +
15.81 + Call_StartFunction(INVALID_HANDLE, func);
15.82 + Call_PushCell(5);
15.83 + Call_PushFloat(7.17);
15.84 + Call_PushString(what);
15.85 + Call_PushStringEx(truth, sizeof(truth), SM_PARAM_STRING_COPY, SM_PARAM_COPYBACK);
15.86 + Call_PushCellRef(a);
15.87 + Call_PushFloatRef(b);
15.88 + Call_PushArrayEx(hello, pm, SM_PARAM_COPYBACK);
15.89 + Call_PushArray(hello, pm);
15.90 + Call_PushCell(pm);
15.91 + Call_PushArray(hello2, 1);
15.92 + err = Call_Finish(ret);
15.93 +
15.94 + PrintToServer("Call to OnCallFuncReceived has finished!");
15.95 + PrintToServer("Error code = %d (expected: %d)", err, 0);
15.96 + PrintToServer("Return value = %d (expected: %d)", ret, 42);
15.97 +
15.98 + PrintToServer("a = %d (expected: %d)", a, 15);
15.99 + PrintToServer("b = %f (expected: %f)", b, 1.5);
15.100 + PrintToServer("what = \"%s\" (expected: \"%s\")", what, "Gaben");
15.101 + PrintToServer("truth = \"%s\" (expected: \"%s\")", truth, "Gaben is fat.");
15.102 + PrintToServer("hello[0] = %d (expected: %d)", hello[0], 5);
15.103 + PrintToServer("hello[1] = %d (expected: %d)", hello[1], 6);
15.104 + PrintToServer("hello2[0] = %d (expected: %d)", hello2[0], 9);
15.105 +
15.106 + return Plugin_Handled;
15.107 +}
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/plugins/testsuite/fwdtest1.sp Fri Mar 16 06:54:24 2007 +0000
16.3 @@ -0,0 +1,169 @@
16.4 +#include <sourcemod>
16.5 +
16.6 +public Plugin:myinfo =
16.7 +{
16.8 + name = "Forward Testing Lab #1",
16.9 + author = "AlliedModders LLC",
16.10 + description = "Tests suite #1 for forwards created by plugins",
16.11 + version = "1.0.0.0",
16.12 + url = "http://www.sourcemod.net/"
16.13 +};
16.14 +
16.15 +new Handle:g_GlobalFwd = INVALID_HANDLE;
16.16 +new Handle:g_PrivateFwd = INVALID_HANDLE;
16.17 +
16.18 +public OnPluginStart()
16.19 +{
16.20 + PrintToServer("OnPluginStart: %d", OnPluginStart);
16.21 +
16.22 + RegServerCmd("test_create_gforward", Command_CreateGlobalForward);
16.23 + RegServerCmd("test_create_pforward", Command_CreatePrivateForward);
16.24 + RegServerCmd("test_exec_gforward", Command_ExecGlobalForward);
16.25 + RegServerCmd("test_exec_pforward", Command_ExecPrivateForward);
16.26 +}
16.27 +
16.28 +public OnPluginEnd()
16.29 +{
16.30 + CloseHandle(g_GlobalFwd);
16.31 + CloseHandle(g_PrivateFwd);
16.32 +}
16.33 +
16.34 +public Action:Command_CreateGlobalForward(args)
16.35 +{
16.36 + if (g_GlobalFwd != INVALID_HANDLE)
16.37 + {
16.38 + CloseHandle(g_GlobalFwd);
16.39 + }
16.40 +
16.41 + g_GlobalFwd = CreateGlobalForward("OnGlobalForward", ET_Ignore, Param_Any, Param_Cell, Param_Float, Param_String, Param_Array, Param_CellByRef, Param_FloatByRef);
16.42 +
16.43 + if (g_GlobalFwd == INVALID_HANDLE)
16.44 + {
16.45 + PrintToServer("Failed to create global forward!");
16.46 + }
16.47 +
16.48 + return Plugin_Handled;
16.49 +}
16.50 +
16.51 +public Action:Command_CreatePrivateForward(args)
16.52 +{
16.53 + new Handle:pl;
16.54 + new Function:func;
16.55 +
16.56 + if (g_PrivateFwd != INVALID_HANDLE)
16.57 + {
16.58 + CloseHandle(g_PrivateFwd);
16.59 + }
16.60 +
16.61 + g_PrivateFwd = CreateForward(ET_Hook, Param_Cell, Param_String, Param_VarArgs);
16.62 +
16.63 + if (g_PrivateFwd == INVALID_HANDLE)
16.64 + {
16.65 + PrintToServer("Failed to create private forward!")
16.66 + }
16.67 +
16.68 + pl = FindPluginByFile("fwdtest2.smx");
16.69 +
16.70 + if (!pl)
16.71 + {
16.72 + PrintToServer("Could not find fwdtest2.smx!");
16.73 + return Plugin_Handled;
16.74 + }
16.75 +
16.76 + func = GetFunctionByName(pl, "OnPrivateForward");
16.77 +
16.78 + /* This shouldn't happen, but oh well */
16.79 + if (func == INVALID_FUNCTION)
16.80 + {
16.81 + PrintToServer("Could not find \"OnPrivateForward\" in fwdtest2.smx!");
16.82 + return Plugin_Handled;
16.83 + }
16.84 +
16.85 + if (!AddToForward(g_PrivateFwd, pl, func) || !AddToForward(g_PrivateFwd, GetMyHandle(), ZohMyGod))
16.86 + {
16.87 + PrintToServer("Failed to add functions to private forward!");
16.88 + return Plugin_Handled;
16.89 + }
16.90 +
16.91 + return Plugin_Handled;
16.92 +}
16.93 +
16.94 +public Action:Command_ExecGlobalForward(args)
16.95 +{
16.96 + new a = 99;
16.97 + new Float:b = 4.215;
16.98 + new err, ret;
16.99 +
16.100 + if (g_GlobalFwd == INVALID_HANDLE)
16.101 + {
16.102 + PrintToServer("Failed to execute global forward. Create it first.");
16.103 + return Plugin_Handled;
16.104 + }
16.105 +
16.106 + PrintToServer("Beginning call to %d functions in global forward \"OnGlobalForward\"", GetForwardFunctionCount(g_GlobalFwd));
16.107 +
16.108 + Call_StartForward(g_GlobalFwd);
16.109 + Call_PushCell(OnPluginStart);
16.110 + Call_PushCell(7);
16.111 + Call_PushFloat(-8.5);
16.112 + Call_PushString("Anata wa doko desu ka?");
16.113 + Call_PushArray({0.0, 1.1, 2.2}, 3);
16.114 + Call_PushCellRef(a);
16.115 + Call_PushFloatRef(b);
16.116 + err = Call_Finish(ret);
16.117 +
16.118 + PrintToServer("Call to global forward \"OnGlobalForward\" completed");
16.119 + PrintToServer("Error code = %d (expected: %d)", err, 0);
16.120 + PrintToServer("Return value = %d (expected: %d)", ret, Plugin_Continue);
16.121 +
16.122 + PrintToServer("a = %d (expected: %d)", a, 777);
16.123 + PrintToServer("b = %f (expected: %f)", b, -0.782);
16.124 +
16.125 + return Plugin_Handled;
16.126 +}
16.127 +
16.128 +public Action:Command_ExecPrivateForward(args)
16.129 +{
16.130 + new err, ret;
16.131 +
16.132 + if (g_PrivateFwd == INVALID_HANDLE)
16.133 + {
16.134 + PrintToServer("Failed to execute private forward. Create it first.");
16.135 + return Plugin_Handled;
16.136 + }
16.137 +
16.138 + PrintToServer("Beginning call to %d functions in private forward", GetForwardFunctionCount(g_PrivateFwd));
16.139 +
16.140 + Call_StartForward(g_PrivateFwd);
16.141 + Call_PushCell(24);
16.142 + Call_PushString("I am a format string: %d %d %d %d %d %d");
16.143 + Call_PushCell(0);
16.144 + Call_PushCell(1);
16.145 + Call_PushCell(2);
16.146 + Call_PushCell(3);
16.147 + Call_PushCell(4);
16.148 + Call_PushCell(5);
16.149 + err = Call_Finish(ret);
16.150 +
16.151 + PrintToServer("Call to private forward completed");
16.152 + PrintToServer("Error code = %d (expected: %d)", err, 0);
16.153 + PrintToServer("Return value = %d (expected: %d)", ret, Plugin_Handled);
16.154 +
16.155 + return Plugin_Handled;
16.156 +}
16.157 +
16.158 +public Action:ZohMyGod(num, const String:format[], ...)
16.159 +{
16.160 + decl String:buffer[128];
16.161 +
16.162 + PrintToServer("Inside private forward #1");
16.163 +
16.164 + PrintToServer("num = %d (expected: %d)", num, 24);
16.165 +
16.166 + VFormat(buffer, sizeof(buffer), format, 3);
16.167 + PrintToServer("buffer = \"%s\" (expected: \"%s\")", buffer, "I am a format string: 0 1 2 3 4 5");
16.168 +
16.169 + PrintToServer("End private forward #1");
16.170 +
16.171 + return Plugin_Continue;
16.172 +}
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/plugins/testsuite/fwdtest2.sp Fri Mar 16 06:54:24 2007 +0000
17.3 @@ -0,0 +1,43 @@
17.4 +#include <sourcemod>
17.5 +
17.6 +public Plugin:myinfo =
17.7 +{
17.8 + name = "Forward Testing Lab #2",
17.9 + author = "AlliedModders LLC",
17.10 + description = "Tests suite #2 for forwards created by plugins",
17.11 + version = "1.0.0.0",
17.12 + url = "http://www.sourcemod.net/"
17.13 +};
17.14 +
17.15 +public Action:OnPrivateForward(num, const String:format[], ...)
17.16 +{
17.17 + decl String:buffer[128];
17.18 +
17.19 + PrintToServer("Inside private forward #2");
17.20 +
17.21 + PrintToServer("num = %d (expected: %d)", num, 24);
17.22 +
17.23 + VFormat(buffer, sizeof(buffer), format, 3);
17.24 + PrintToServer("buffer = \"%s\" (expected: \"%s\")", buffer, "I am a format string: 0 1 2 3 4 5");
17.25 +
17.26 + PrintToServer("End private forward #2");
17.27 +
17.28 + return Plugin_Handled;
17.29 +}
17.30 +
17.31 +public OnGlobalForward(Function:a, b, Float:c, const String:d[], Float:e[3], &f, &Float:g)
17.32 +{
17.33 + PrintToServer("Inside global forward \"OnGlobalForward\"");
17.34 +
17.35 + PrintToServer("a = %d (expected: %d)", a, 11);
17.36 + PrintToServer("b = %d (expected: %d)", b, 7);
17.37 + PrintToServer("c = %f (expected: %f)", c, -8.5);
17.38 + PrintToServer("d = \"%s\" (expected: \"%s\")", d, "Anata wa doko desu ka?");
17.39 + PrintToServer("e = %f %f %f (expected: %f %f %f)", e[0], e[1], e[2], 0.0, 1.1, 2.2);
17.40 +
17.41 + PrintToServer("f = %d (expected %d, setting to %d)", f, 99, 777);
17.42 + f = 777;
17.43 +
17.44 + PrintToServer("g = %f (expected %f, setting to %f)", g, 4.215, -0.782);
17.45 + g = -0.782;
17.46 +}
18.1 --- a/public/IForwardSys.h Thu Mar 15 22:32:45 2007 +0000
18.2 +++ b/public/IForwardSys.h Fri Mar 16 06:54:24 2007 +0000
18.3 @@ -227,6 +227,16 @@
18.4 * @return True on success, otherwise false.
18.5 */
18.6 virtual bool AddFunction(IPluginContext *ctx, funcid_t index) =0;
18.7 +
18.8 + /**
18.9 + * @brief Removes a function from the call list.
18.10 + * NOTE: Only removes one instance.
18.11 + *
18.12 + * @param ctx Context to use as a look-up.
18.13 + * @param index Function id to add.
18.14 + * @return Whether or not the function was removed.
18.15 + */
18.16 + virtual bool RemoveFunction(IPluginContext *ctx, funcid_t index) =0;
18.17 };
18.18
18.19 #define SP_PARAMTYPE_ANY 0