1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/core/smn_events.cpp Sun Mar 30 07:00:22 2008 +0000
1.3 @@ -0,0 +1,369 @@
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 "sm_globals.h"
1.36 +#include "sourcemm_api.h"
1.37 +#include "HandleSys.h"
1.38 +#include "EventManager.h"
1.39 +
1.40 +static cell_t sm_HookEvent(IPluginContext *pContext, const cell_t *params)
1.41 +{
1.42 + char *name;
1.43 + IPluginFunction *pFunction;
1.44 +
1.45 + pContext->LocalToString(params[1], &name);
1.46 + pFunction = pContext->GetFunctionById(params[2]);
1.47 +
1.48 + if (!pFunction)
1.49 + {
1.50 + return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
1.51 + }
1.52 +
1.53 + if (g_EventManager.HookEvent(name, pFunction, static_cast<EventHookMode>(params[3])) == EventHookErr_InvalidEvent)
1.54 + {
1.55 + return pContext->ThrowNativeError("Game event \"%s\" does not exist", name);
1.56 + }
1.57 +
1.58 + return 1;
1.59 +}
1.60 +
1.61 +static cell_t sm_HookEventEx(IPluginContext *pContext, const cell_t *params)
1.62 +{
1.63 + char *name;
1.64 + IPluginFunction *pFunction;
1.65 +
1.66 + pContext->LocalToString(params[1], &name);
1.67 + pFunction = pContext->GetFunctionById(params[2]);
1.68 +
1.69 + if (!pFunction)
1.70 + {
1.71 + return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
1.72 + }
1.73 +
1.74 + if (g_EventManager.HookEvent(name, pFunction, static_cast<EventHookMode>(params[3])) == EventHookErr_InvalidEvent)
1.75 + {
1.76 + return 0;
1.77 + }
1.78 +
1.79 + return 1;
1.80 +}
1.81 +
1.82 +static cell_t sm_UnhookEvent(IPluginContext *pContext, const cell_t *params)
1.83 +{
1.84 + char *name;
1.85 + IPluginFunction *pFunction;
1.86 +
1.87 + pContext->LocalToString(params[1], &name);
1.88 + pFunction = pContext->GetFunctionById(params[2]);
1.89 +
1.90 + if (!pFunction)
1.91 + {
1.92 + return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
1.93 + }
1.94 +
1.95 + EventHookError err = g_EventManager.UnhookEvent(name, pFunction, static_cast<EventHookMode>(params[3]));
1.96 +
1.97 + /* Possible errors that UnhookGameEvent can return */
1.98 + if (err == EventHookErr_NotActive)
1.99 + {
1.100 + return pContext->ThrowNativeError("Game event \"%s\" has no active hook", name);
1.101 + } else if (err == EventHookErr_InvalidCallback) {
1.102 + return pContext->ThrowNativeError("Invalid hook callback specified for game event \"%s\"", name);
1.103 + }
1.104 +
1.105 + return 1;
1.106 +}
1.107 +
1.108 +static cell_t sm_CreateEvent(IPluginContext *pContext, const cell_t *params)
1.109 +{
1.110 + char *name;
1.111 + EventInfo *pInfo;
1.112 +
1.113 + pContext->LocalToString(params[1], &name);
1.114 +
1.115 + pInfo = g_EventManager.CreateEvent(pContext, name, params[2] ? true : false);
1.116 +
1.117 + if (pInfo)
1.118 + {
1.119 + return g_HandleSys.CreateHandle(g_EventManager.GetHandleType(), pInfo, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.120 + }
1.121 +
1.122 + return BAD_HANDLE;
1.123 +}
1.124 +
1.125 +static cell_t sm_FireEvent(IPluginContext *pContext, const cell_t *params)
1.126 +{
1.127 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.128 + HandleError err;
1.129 + EventInfo *pInfo;
1.130 +
1.131 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.132 + != HandleError_None)
1.133 + {
1.134 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.135 + }
1.136 +
1.137 + /* If identities do not match, don't fire event */
1.138 + if (pContext->GetIdentity() != pInfo->pOwner)
1.139 + {
1.140 + return pContext->ThrowNativeError("Game event \"%s\" could not be fired because it was not created by this plugin", pInfo->pEvent->GetName());
1.141 + }
1.142 +
1.143 + g_EventManager.FireEvent(pInfo, params[2] ? true : false);
1.144 +
1.145 + /* Free handle on game event */
1.146 + HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
1.147 + g_HandleSys.FreeHandle(hndl, &sec);
1.148 +
1.149 + return 1;
1.150 +}
1.151 +
1.152 +static cell_t sm_CancelCreatedEvent(IPluginContext *pContext, const cell_t *params)
1.153 +{
1.154 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.155 + HandleError err;
1.156 + EventInfo *pInfo;
1.157 +
1.158 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.159 + != HandleError_None)
1.160 + {
1.161 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.162 + }
1.163 +
1.164 + /* If identities do not match, don't cancel event */
1.165 + if (pContext->GetIdentity() != pInfo->pOwner)
1.166 + {
1.167 + return pContext->ThrowNativeError("Game event \"%s\" could not be canceled because it was not created by this plugin", pInfo->pEvent->GetName());
1.168 + }
1.169 +
1.170 + g_EventManager.CancelCreatedEvent(pInfo);
1.171 +
1.172 + /* Free handle on game event */
1.173 + HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
1.174 + g_HandleSys.FreeHandle(hndl, &sec);
1.175 +
1.176 + return 1;
1.177 +}
1.178 +
1.179 +static cell_t sm_GetEventName(IPluginContext *pContext, const cell_t *params)
1.180 +{
1.181 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.182 + HandleError err;
1.183 + EventInfo *pInfo;
1.184 +
1.185 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.186 + != HandleError_None)
1.187 + {
1.188 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.189 + }
1.190 +
1.191 + pContext->StringToLocalUTF8(params[2], params[3], pInfo->pEvent->GetName(), NULL);
1.192 +
1.193 + return 1;
1.194 +}
1.195 +
1.196 +static cell_t sm_GetEventBool(IPluginContext *pContext, const cell_t *params)
1.197 +{
1.198 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.199 + HandleError err;
1.200 + EventInfo *pInfo;
1.201 +
1.202 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.203 + != HandleError_None)
1.204 + {
1.205 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.206 + }
1.207 +
1.208 + char *key;
1.209 + pContext->LocalToString(params[2], &key);
1.210 +
1.211 + return pInfo->pEvent->GetBool(key);
1.212 +}
1.213 +
1.214 +static cell_t sm_GetEventInt(IPluginContext *pContext, const cell_t *params)
1.215 +{
1.216 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.217 + HandleError err;
1.218 + EventInfo *pInfo;
1.219 +
1.220 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.221 + != HandleError_None)
1.222 + {
1.223 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.224 + }
1.225 +
1.226 + char *key;
1.227 + pContext->LocalToString(params[2], &key);
1.228 +
1.229 + return pInfo->pEvent->GetInt(key);
1.230 +}
1.231 +
1.232 +static cell_t sm_GetEventFloat(IPluginContext *pContext, const cell_t *params)
1.233 +{
1.234 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.235 + HandleError err;
1.236 + EventInfo *pInfo;
1.237 +
1.238 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.239 + != HandleError_None)
1.240 + {
1.241 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.242 + }
1.243 +
1.244 + char *key;
1.245 + pContext->LocalToString(params[2], &key);
1.246 +
1.247 + float value = pInfo->pEvent->GetFloat(key);
1.248 +
1.249 + return sp_ftoc(value);
1.250 +}
1.251 +
1.252 +static cell_t sm_GetEventString(IPluginContext *pContext, const cell_t *params)
1.253 +{
1.254 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.255 + HandleError err;
1.256 + EventInfo *pInfo;
1.257 +
1.258 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.259 + != HandleError_None)
1.260 + {
1.261 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.262 + }
1.263 +
1.264 + char *key;
1.265 + pContext->LocalToString(params[2], &key);
1.266 +
1.267 + pContext->StringToLocalUTF8(params[3], params[4], pInfo->pEvent->GetString(key), NULL);
1.268 +
1.269 + return 1;
1.270 +}
1.271 +
1.272 +static cell_t sm_SetEventBool(IPluginContext *pContext, const cell_t *params)
1.273 +{
1.274 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.275 + HandleError err;
1.276 + EventInfo *pInfo;
1.277 +
1.278 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.279 + != HandleError_None)
1.280 + {
1.281 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.282 + }
1.283 +
1.284 + char *key;
1.285 + pContext->LocalToString(params[2], &key);
1.286 +
1.287 + pInfo->pEvent->SetBool(key, params[3] ? true : false);
1.288 +
1.289 + return 1;
1.290 +}
1.291 +
1.292 +static cell_t sm_SetEventInt(IPluginContext *pContext, const cell_t *params)
1.293 +{
1.294 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.295 + HandleError err;
1.296 + EventInfo *pInfo;
1.297 +
1.298 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.299 + != HandleError_None)
1.300 + {
1.301 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.302 + }
1.303 +
1.304 + char *key;
1.305 + pContext->LocalToString(params[2], &key);
1.306 +
1.307 + pInfo->pEvent->SetInt(key, params[3]);
1.308 +
1.309 + return 1;
1.310 +}
1.311 +
1.312 +static cell_t sm_SetEventFloat(IPluginContext *pContext, const cell_t *params)
1.313 +{
1.314 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.315 + HandleError err;
1.316 + EventInfo *pInfo;
1.317 +
1.318 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.319 + != HandleError_None)
1.320 + {
1.321 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.322 + }
1.323 +
1.324 + char *key;
1.325 + pContext->LocalToString(params[2], &key);
1.326 +
1.327 + float value = sp_ctof(params[3]);
1.328 + pInfo->pEvent->SetFloat(key, value);
1.329 +
1.330 + return 1;
1.331 +}
1.332 +
1.333 +static cell_t sm_SetEventString(IPluginContext *pContext, const cell_t *params)
1.334 +{
1.335 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.336 + HandleError err;
1.337 + EventInfo *pInfo;
1.338 +
1.339 + if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
1.340 + != HandleError_None)
1.341 + {
1.342 + return pContext->ThrowNativeError("Invalid game event handle %x (error %d)", hndl, err);
1.343 + }
1.344 +
1.345 + char *key, *value;
1.346 + pContext->LocalToString(params[2], &key);
1.347 + pContext->LocalToString(params[3], &value);
1.348 +
1.349 + pInfo->pEvent->SetString(key, value);
1.350 +
1.351 + return 1;
1.352 +}
1.353 +
1.354 +REGISTER_NATIVES(gameEventNatives)
1.355 +{
1.356 + {"HookEvent", sm_HookEvent},
1.357 + {"HookEventEx", sm_HookEventEx},
1.358 + {"UnhookEvent", sm_UnhookEvent},
1.359 + {"CreateEvent", sm_CreateEvent},
1.360 + {"FireEvent", sm_FireEvent},
1.361 + {"CancelCreatedEvent", sm_CancelCreatedEvent},
1.362 + {"GetEventName", sm_GetEventName},
1.363 + {"GetEventBool", sm_GetEventBool},
1.364 + {"GetEventInt", sm_GetEventInt},
1.365 + {"GetEventFloat", sm_GetEventFloat},
1.366 + {"GetEventString", sm_GetEventString},
1.367 + {"SetEventBool", sm_SetEventBool},
1.368 + {"SetEventInt", sm_SetEventInt},
1.369 + {"SetEventFloat", sm_SetEventFloat},
1.370 + {"SetEventString", sm_SetEventString},
1.371 + {NULL, NULL}
1.372 +};