1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/core/logic/smn_datapacks.cpp Fri May 14 21:16:35 2010 -0700
1.3 @@ -0,0 +1,329 @@
1.4 +/**
1.5 + * vim: set ts=4 sw=4 tw=99 noet :
1.6 + * =============================================================================
1.7 + * SourceMod
1.8 + * Copyright (C) 2004-2010 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 "common_logic.h"
1.36 +#include <IHandleSys.h>
1.37 +#include <IDataPack.h>
1.38 +#include <ISourceMod.h>
1.39 +
1.40 +HandleType_t g_DataPackType;
1.41 +
1.42 +class DataPackNatives :
1.43 + public SMGlobalClass,
1.44 + public IHandleTypeDispatch
1.45 +{
1.46 +public:
1.47 + void OnSourceModAllInitialized()
1.48 + {
1.49 + HandleAccess hacc;
1.50 + TypeAccess tacc;
1.51 +
1.52 + handlesys->InitAccessDefaults(&tacc, &hacc);
1.53 + tacc.access[HTypeAccess_Create] = true;
1.54 + tacc.access[HTypeAccess_Inherit] = true;
1.55 + tacc.ident = g_pCoreIdent;
1.56 + hacc.access[HandleAccess_Read] = HANDLE_RESTRICT_OWNER;
1.57 +
1.58 + g_DataPackType = handlesys->CreateType("DataPack", this, 0, &tacc, &hacc, g_pCoreIdent, NULL);
1.59 + }
1.60 + void OnSourceModShutdown()
1.61 + {
1.62 + handlesys->RemoveType(g_DataPackType, g_pCoreIdent);
1.63 + g_DataPackType = 0;
1.64 + }
1.65 + void OnHandleDestroy(HandleType_t type, void *object)
1.66 + {
1.67 + g_pSM->FreeDataPack(reinterpret_cast<IDataPack *>(object));
1.68 + }
1.69 +};
1.70 +
1.71 +static cell_t smn_CreateDataPack(IPluginContext *pContext, const cell_t *params)
1.72 +{
1.73 + IDataPack *pDataPack = g_pSM->CreateDataPack();
1.74 +
1.75 + if (!pDataPack)
1.76 + {
1.77 + return 0;
1.78 + }
1.79 +
1.80 + return handlesys->CreateHandle(g_DataPackType, pDataPack, pContext->GetIdentity(), g_pCoreIdent, NULL);
1.81 +}
1.82 +
1.83 +static cell_t smn_WritePackCell(IPluginContext *pContext, const cell_t *params)
1.84 +{
1.85 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.86 + HandleError herr;
1.87 + HandleSecurity sec;
1.88 + IDataPack *pDataPack;
1.89 +
1.90 + sec.pOwner = pContext->GetIdentity();
1.91 + sec.pIdentity = g_pCoreIdent;
1.92 +
1.93 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.94 + != HandleError_None)
1.95 + {
1.96 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.97 + }
1.98 +
1.99 + pDataPack->PackCell(params[2]);
1.100 +
1.101 + return 1;
1.102 +}
1.103 +
1.104 +static cell_t smn_WritePackFloat(IPluginContext *pContext, const cell_t *params)
1.105 +{
1.106 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.107 + HandleError herr;
1.108 + HandleSecurity sec;
1.109 + IDataPack *pDataPack;
1.110 +
1.111 + sec.pOwner = pContext->GetIdentity();
1.112 + sec.pIdentity = g_pCoreIdent;
1.113 +
1.114 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.115 + != HandleError_None)
1.116 + {
1.117 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.118 + }
1.119 +
1.120 + pDataPack->PackFloat(sp_ctof(params[2]));
1.121 +
1.122 + return 1;
1.123 +}
1.124 +
1.125 +static cell_t smn_WritePackString(IPluginContext *pContext, const cell_t *params)
1.126 +{
1.127 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.128 + HandleError herr;
1.129 + HandleSecurity sec;
1.130 + IDataPack *pDataPack;
1.131 + int err;
1.132 +
1.133 + sec.pOwner = pContext->GetIdentity();
1.134 + sec.pIdentity = g_pCoreIdent;
1.135 +
1.136 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.137 + != HandleError_None)
1.138 + {
1.139 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.140 + }
1.141 +
1.142 + char *str;
1.143 + if ((err=pContext->LocalToString(params[2], &str)) != SP_ERROR_NONE)
1.144 + {
1.145 + pContext->ThrowNativeErrorEx(err, NULL);
1.146 + return 0;
1.147 + }
1.148 +
1.149 + pDataPack->PackString(str);
1.150 +
1.151 + return 1;
1.152 +}
1.153 +
1.154 +static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
1.155 +{
1.156 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.157 + HandleError herr;
1.158 + HandleSecurity sec;
1.159 + IDataPack *pDataPack;
1.160 +
1.161 + sec.pOwner = pContext->GetIdentity();
1.162 + sec.pIdentity = g_pCoreIdent;
1.163 +
1.164 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.165 + != HandleError_None)
1.166 + {
1.167 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.168 + }
1.169 +
1.170 + if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(cell_t)))
1.171 + {
1.172 + return pContext->ThrowNativeError("DataPack operation is out of bounds.");
1.173 + }
1.174 +
1.175 + return pDataPack->ReadCell();
1.176 +}
1.177 +
1.178 +static cell_t smn_ReadPackFloat(IPluginContext *pContext, const cell_t *params)
1.179 +{
1.180 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.181 + HandleError herr;
1.182 + HandleSecurity sec;
1.183 + IDataPack *pDataPack;
1.184 +
1.185 + sec.pOwner = pContext->GetIdentity();
1.186 + sec.pIdentity = g_pCoreIdent;
1.187 +
1.188 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.189 + != HandleError_None)
1.190 + {
1.191 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.192 + }
1.193 +
1.194 + if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(float)))
1.195 + {
1.196 + return pContext->ThrowNativeError("DataPack operation is out of bounds.");
1.197 + }
1.198 +
1.199 + return sp_ftoc(pDataPack->ReadFloat());
1.200 +}
1.201 +
1.202 +static cell_t smn_ReadPackString(IPluginContext *pContext, const cell_t *params)
1.203 +{
1.204 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.205 + HandleError herr;
1.206 + HandleSecurity sec;
1.207 + IDataPack *pDataPack;
1.208 +
1.209 + sec.pOwner = pContext->GetIdentity();
1.210 + sec.pIdentity = g_pCoreIdent;
1.211 +
1.212 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.213 + != HandleError_None)
1.214 + {
1.215 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.216 + }
1.217 +
1.218 + const char *str;
1.219 + if (!(str=pDataPack->ReadString(NULL)))
1.220 + {
1.221 + return pContext->ThrowNativeError("DataPack operation is out of bounds.");
1.222 + }
1.223 +
1.224 + pContext->StringToLocal(params[2], params[3], str);
1.225 +
1.226 + return 1;
1.227 +}
1.228 +
1.229 +static cell_t smn_ResetPack(IPluginContext *pContext, const cell_t *params)
1.230 +{
1.231 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.232 + HandleError herr;
1.233 + HandleSecurity sec;
1.234 + IDataPack *pDataPack;
1.235 +
1.236 + sec.pOwner = pContext->GetIdentity();
1.237 + sec.pIdentity = g_pCoreIdent;
1.238 +
1.239 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.240 + != HandleError_None)
1.241 + {
1.242 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.243 + }
1.244 +
1.245 + pDataPack->Reset();
1.246 + if (params[2])
1.247 + {
1.248 + pDataPack->ResetSize();
1.249 + }
1.250 +
1.251 + return 1;
1.252 +}
1.253 +
1.254 +static cell_t smn_GetPackPosition(IPluginContext *pContext, const cell_t *params)
1.255 +{
1.256 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.257 + HandleError herr;
1.258 + HandleSecurity sec;
1.259 + IDataPack *pDataPack;
1.260 +
1.261 + sec.pOwner = pContext->GetIdentity();
1.262 + sec.pIdentity = g_pCoreIdent;
1.263 +
1.264 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.265 + != HandleError_None)
1.266 + {
1.267 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.268 + }
1.269 +
1.270 + return static_cast<cell_t>(pDataPack->GetPosition());
1.271 +}
1.272 +
1.273 +static cell_t smn_SetPackPosition(IPluginContext *pContext, const cell_t *params)
1.274 +{
1.275 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.276 + HandleError herr;
1.277 + HandleSecurity sec;
1.278 + IDataPack *pDataPack;
1.279 +
1.280 + sec.pOwner = pContext->GetIdentity();
1.281 + sec.pIdentity = g_pCoreIdent;
1.282 +
1.283 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.284 + != HandleError_None)
1.285 + {
1.286 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.287 + }
1.288 +
1.289 + if (!pDataPack->SetPosition(params[2]))
1.290 + {
1.291 + return pContext->ThrowNativeError("Invalid DataPack position, %d is out of bounds", params[2]);
1.292 + }
1.293 +
1.294 + return 1;
1.295 +}
1.296 +
1.297 +static cell_t smn_IsPackReadable(IPluginContext *pContext, const cell_t *params)
1.298 +{
1.299 + Handle_t hndl = static_cast<Handle_t>(params[1]);
1.300 + HandleError herr;
1.301 + HandleSecurity sec;
1.302 + IDataPack *pDataPack;
1.303 +
1.304 + sec.pOwner = pContext->GetIdentity();
1.305 + sec.pIdentity = g_pCoreIdent;
1.306 +
1.307 + if ((herr=handlesys->ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
1.308 + != HandleError_None)
1.309 + {
1.310 + return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
1.311 + }
1.312 +
1.313 + return pDataPack->IsReadable(params[2]) ? 1 : 0;
1.314 +}
1.315 +
1.316 +static DataPackNatives s_DataPackNatives;
1.317 +
1.318 +REGISTER_NATIVES(datapacknatives)
1.319 +{
1.320 + {"CreateDataPack", smn_CreateDataPack},
1.321 + {"WritePackCell", smn_WritePackCell},
1.322 + {"WritePackFloat", smn_WritePackFloat},
1.323 + {"WritePackString", smn_WritePackString},
1.324 + {"ReadPackCell", smn_ReadPackCell},
1.325 + {"ReadPackFloat", smn_ReadPackFloat},
1.326 + {"ReadPackString", smn_ReadPackString},
1.327 + {"ResetPack", smn_ResetPack},
1.328 + {"GetPackPosition", smn_GetPackPosition},
1.329 + {"SetPackPosition", smn_SetPackPosition},
1.330 + {"IsPackReadable", smn_IsPackReadable},
1.331 + {NULL, NULL}
1.332 +};