Update CS:GO team score gamedata.
3 * =============================================================================
4 * SourceMod SDKTools Extension
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "smsdk_ext.h"
33 #include "extension.h"
35 #include "vcallbuilder.h"
37 using namespace SourceMod;
38 using namespace SourcePawn;
41 * For object pointers, the data looks like this instead:
42 * 4 bytes: POINTER TO LATER
43 * + bytes: Object internal data
45 * We use the virtual stack as extra fake stack space and create a temp object.
46 * If these objects had destructors, we'd need to fake destroy toom of course.
47 * Of course, BinTools only reads the first four bytes and passes the pointer.
50 size_t ValveParamToBinParam(ValveType type,
61 size_t mySize = sizeof(Vector *);
62 if (pass == PassType_Basic)
64 if (flags & PASSFLAG_BYREF)
68 info->type = PassType_Basic;
70 info->size = sizeof(Vector *);
71 mySize = sizeof(Vector);
73 } else if (pass == PassType_Object) {
74 info->type = PassType_Object;
75 info->flags = flags | PASSFLAG_OASSIGNOP | PASSFLAG_OCTOR;
76 info->size = sizeof(Vector);
84 size_t mySize = sizeof(QAngle *);
85 if (pass == PassType_Basic)
87 if (flags & PASSFLAG_BYREF)
91 info->type = PassType_Basic;
93 info->size = sizeof(QAngle *);
94 mySize = sizeof(QAngle);
96 } else if (pass == PassType_Object) {
97 info->type = PassType_Object;
98 info->flags = flags | PASSFLAG_OASSIGNOP | PASSFLAG_OCTOR;
99 info->size = sizeof(QAngle);
105 case Valve_CBaseEntity:
106 case Valve_CBasePlayer:
110 if (pass != PassType_Basic || (flags & PASSFLAG_BYREF))
114 info->type = PassType_Basic;
116 info->size = sizeof(void *);
117 return sizeof(void *);
121 info->type = PassType_Basic;
123 if (flags & PASSFLAG_ASPOINTER)
126 info->size = sizeof(int *);
127 return sizeof(int *) + sizeof(int);
129 info->size = sizeof(int);
135 info->type = PassType_Basic;
137 if (flags & PASSFLAG_ASPOINTER)
140 info->size = sizeof(bool *);
141 return sizeof(bool *) + sizeof(bool);
143 info->size = sizeof(bool);
150 if (flags & PASSFLAG_ASPOINTER)
153 info->type = PassType_Basic;
154 info->size = sizeof(float *);
155 return sizeof(float *) + sizeof(float);
157 info->type = PassType_Float;
158 info->size = sizeof(float);
159 return sizeof(float);
167 DataStatus EncodeValveParam(IPluginContext *pContext,
169 const ValveCall *pCall,
170 const ValvePassInfo *data,
173 const void *buffer = (const unsigned char *)_buffer + data->offset;
180 if (data->type == PassType_Basic)
182 v = *(Vector **)buffer;
183 } else if (data->type == PassType_Object) {
184 v = (Vector *)buffer;
188 pContext->LocalToPhysAddr(param, &addr);
190 addr[0] = sp_ftoc(v->x);
191 addr[1] = sp_ftoc(v->y);
192 addr[2] = sp_ftoc(v->z);
200 if (data->type == PassType_Basic)
202 q = *(QAngle **)buffer;
203 } else if (data->type == PassType_Object) {
204 q = (QAngle *)buffer;
208 pContext->LocalToPhysAddr(param, &addr);
210 addr[0] = sp_ftoc(q->x);
211 addr[1] = sp_ftoc(q->y);
212 addr[2] = sp_ftoc(q->z);
216 case Valve_CBaseEntity:
217 case Valve_CBasePlayer:
220 pContext->LocalToPhysAddr(param, &addr);
222 CBaseEntity *pEntity = *(CBaseEntity **)buffer;
225 *addr = gamehelpers->EntityToBCompatRef(pEntity);
235 pContext->LocalToPhysAddr(param, &addr);
237 edict_t *pEdict = *(edict_t **)buffer;
240 *addr = IndexOfEdict(pEdict);
251 pContext->LocalToPhysAddr(param, &addr);
253 if (data->flags & PASSFLAG_ASPOINTER)
255 buffer = *(cell_t **)buffer;
258 *addr = *(cell_t *)buffer;
265 pContext->LocalToPhysAddr(param, &addr);
267 if (data->flags & PASSFLAG_ASPOINTER)
269 buffer = *(bool **)buffer;
272 *addr = *(bool *)buffer ? 1 : 0;
281 DataStatus DecodeValveParam(IPluginContext *pContext,
283 const ValveCall *pCall,
284 const ValvePassInfo *data,
287 void *buffer = (unsigned char *)_buffer + data->offset;
294 err = pContext->LocalToPhysAddr(param, &addr);
296 unsigned char *mem = (unsigned char *)buffer;
297 if (data->type == PassType_Basic)
299 /* Store the object in the next N bytes, and store
300 * a pointer to that object right beforehand.
302 Vector **realPtr = (Vector **)buffer;
304 if (addr == pContext->GetNullRef(SP_NULL_VECTOR))
306 if (data->decflags & VDECODE_FLAG_ALLOWNULL)
311 pContext->ThrowNativeError("NULL not allowed");
315 mem = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset;
316 *realPtr = (Vector *)mem;
320 if (err != SP_ERROR_NONE)
322 pContext->ThrowNativeErrorEx(err, "Could not read plugin data");
326 /* Use placement new to initialize the object cleanly
327 * This has no destructor so we don't need to do
328 * DestroyValveParam() or something :]
330 Vector *v = new (mem) Vector(
341 err = pContext->LocalToPhysAddr(param, &addr);
343 unsigned char *mem = (unsigned char *)buffer;
344 if (data->type == PassType_Basic)
346 /* Store the object in the next N bytes, and store
347 * a pointer to that object right beforehand.
349 QAngle **realPtr = (QAngle **)buffer;
351 if (addr == pContext->GetNullRef(SP_NULL_VECTOR))
353 if (!(data->decflags & VDECODE_FLAG_ALLOWNULL))
355 pContext->ThrowNativeError("NULL not allowed");
362 mem = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset;
363 *realPtr = (QAngle *)mem;
367 if (err != SP_ERROR_NONE)
369 pContext->ThrowNativeErrorEx(err, "Could not read plugin data");
373 /* Use placement new to initialize the object cleanly
374 * This has no destructor so we don't need to do
375 * DestroyValveParam() or something :]
377 QAngle *v = new (mem) QAngle(
384 case Valve_CBasePlayer:
386 CBaseEntity *pEntity = NULL;
387 if (data->decflags & VDECODE_FLAG_BYREF)
390 pContext->LocalToPhysAddr(param, &addr);
393 int index = gamehelpers->ReferenceToIndex(param);
394 if ((unsigned)index == INVALID_EHANDLE_INDEX && param != -1)
398 if (index >= 1 && index <= playerhelpers->GetMaxClients())
400 IGamePlayer *player = playerhelpers->GetGamePlayer(index);
401 if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
402 && !player->IsConnected())
404 pContext->ThrowNativeError("Client %d is not connected", param);
406 } else if (!player->IsInGame()) {
407 pContext->ThrowNativeError("Client %d is not in game", param);
410 pEntity = gamehelpers->ReferenceToEntity(param);
411 } else if (param == -1) {
412 if (data->decflags & VDECODE_FLAG_ALLOWNULL)
416 pContext->ThrowNativeError("NULL not allowed");
420 pContext->ThrowNativeError("Entity index %d is not a valid client", param);
424 CBaseEntity **ebuf = (CBaseEntity **)buffer;
429 case Valve_CBaseEntity:
431 CBaseEntity *pEntity = NULL;
432 if (data->decflags & VDECODE_FLAG_BYREF)
435 pContext->LocalToPhysAddr(param, &addr);
438 int index = gamehelpers->ReferenceToIndex(param);
439 if ((unsigned)index == INVALID_EHANDLE_INDEX && param != -1)
443 if (index >= 1 && index <= playerhelpers->GetMaxClients())
445 IGamePlayer *player = playerhelpers->GetGamePlayer(index);
446 if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
447 && !player->IsConnected())
449 pContext->ThrowNativeError("Client %d is not connected", param);
451 } else if (!player->IsInGame()) {
452 pContext->ThrowNativeError("Client %d is not in game", param);
455 pEntity = gamehelpers->ReferenceToEntity(param);
456 } else if (param == -1) {
457 if (data->decflags & VDECODE_FLAG_ALLOWNULL)
461 pContext->ThrowNativeError("NULL not allowed");
464 } else if (index == 0) {
465 if (data->decflags & VDECODE_FLAG_ALLOWWORLD)
467 pEntity = gamehelpers->ReferenceToEntity(0);
469 pContext->ThrowNativeError("World not allowed");
473 pEntity = gamehelpers->ReferenceToEntity(param);
476 pContext->ThrowNativeError("Entity %d is not valid", param);
481 CBaseEntity **ebuf = (CBaseEntity **)buffer;
489 if (data->decflags & VDECODE_FLAG_BYREF)
492 pContext->LocalToPhysAddr(param, &addr);
495 if (param >= 1 && param <= playerhelpers->GetMaxClients())
497 IGamePlayer *player = playerhelpers->GetGamePlayer(param);
498 if ((data->decflags & VDECODE_FLAG_ALLOWNOTINGAME)
499 && !player->IsConnected())
501 pContext->ThrowNativeError("Client %d is not connected", param);
503 } else if (!player->IsInGame()) {
504 pContext->ThrowNativeError("Client %d is not in game", param);
507 pEdict = player->GetEdict();
508 } else if (param == -1) {
509 if (data->decflags & VDECODE_FLAG_ALLOWNULL)
513 pContext->ThrowNativeError("NULL not allowed");
516 } else if (param == 0) {
517 if (data->decflags & VDECODE_FLAG_ALLOWWORLD)
519 pEdict = PEntityOfEntIndex(0);
521 pContext->ThrowNativeError("World not allowed");
525 pEdict = PEntityOfEntIndex(param);
526 if (!pEdict || pEdict->IsFree())
528 pContext->ThrowNativeError("Entity %d is not valid or is freed", param);
533 edict_t **ebuf = (edict_t **)buffer;
541 if (data->decflags & VDECODE_FLAG_BYREF)
544 pContext->LocalToPhysAddr(param, &addr);
547 if (data->flags & PASSFLAG_ASPOINTER)
549 *(void **)buffer = (unsigned char *)_buffer + pCall->stackEnd + data->obj_offset;
550 buffer = *(void **)buffer;
552 *(cell_t *)buffer = param;
557 if (data->decflags & VDECODE_FLAG_BYREF)
560 pContext->LocalToPhysAddr(param, &addr);
563 if (data->flags & PASSFLAG_ASPOINTER)
565 *(bool **)buffer = (bool *)((unsigned char *)_buffer + pCall->stackEnd + data->obj_offset);
566 buffer = *(bool **)buffer;
568 *(bool *)buffer = param ? true : false;
574 pContext->LocalToString(param, &addr);
575 *(char **)buffer = addr;