2013-01-23 03:43:12 +01:00
|
|
|
/**
|
|
|
|
* vim: set ts=4 :
|
|
|
|
* =============================================================================
|
|
|
|
* SourceMod
|
|
|
|
* Copyright (C) 2013 AlliedModders LLC. All rights reserved.
|
|
|
|
* =============================================================================
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it under
|
|
|
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
|
|
|
* Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
|
* details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with
|
|
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* As a special exception, AlliedModders LLC gives you permission to link the
|
|
|
|
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
|
|
|
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
|
|
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
|
|
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
|
|
|
* this exception to all derivative works. AlliedModders LLC defines further
|
|
|
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
|
|
|
* or <http://www.sourcemod.net/license.php>.
|
|
|
|
*
|
|
|
|
* Version: $Id$
|
|
|
|
*/
|
|
|
|
|
2013-03-29 20:35:56 +01:00
|
|
|
#include "logic_bridge.h"
|
2013-04-15 13:22:23 +02:00
|
|
|
#include "UserMessages.h"
|
2013-01-23 03:43:12 +01:00
|
|
|
#include "UserMessagePBHelpers.h"
|
|
|
|
#include "smn_usermsgs.h"
|
|
|
|
|
|
|
|
// Assumes pbuf message handle is param 1, gets message as msg
|
|
|
|
#define GET_MSG_FROM_HANDLE_OR_ERR() \
|
|
|
|
Handle_t hndl = static_cast<Handle_t>(params[1]); \
|
|
|
|
HandleError herr; \
|
|
|
|
HandleSecurity sec; \
|
|
|
|
SMProtobufMessage *msg; \
|
|
|
|
\
|
|
|
|
sec.pOwner = NULL; \
|
|
|
|
sec.pIdentity = g_pCoreIdent; \
|
|
|
|
\
|
2013-03-29 19:37:29 +01:00
|
|
|
if ((herr=handlesys->ReadHandle(hndl, g_ProtobufType, &sec, (void **)&msg)) \
|
2013-01-23 03:43:12 +01:00
|
|
|
!= HandleError_None) \
|
|
|
|
{ \
|
|
|
|
return pCtx->ThrowNativeError("Invalid protobuf message handle %x (error %d)", hndl, herr); \
|
|
|
|
}
|
|
|
|
|
|
|
|
// Assumes message field name is param 2, gets as strField
|
|
|
|
#define GET_FIELD_NAME_OR_ERR() \
|
|
|
|
int err; \
|
|
|
|
char *strField; \
|
|
|
|
if ((err=pCtx->LocalToString(params[2], &strField)) != SP_ERROR_NONE) \
|
|
|
|
{ \
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL); \
|
|
|
|
return 0; \
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadInt(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
int ret;
|
2013-03-16 18:31:35 +01:00
|
|
|
|
|
|
|
int index = params[0] >= 3 ? params[3] : -1;
|
|
|
|
if (index < 0)
|
|
|
|
{
|
2013-04-16 17:33:36 +02:00
|
|
|
if (!msg->GetInt32OrUnsignedOrEnum(strField, &ret))
|
2013-03-16 18:31:35 +01:00
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-04-16 17:33:36 +02:00
|
|
|
if (!msg->GetRepeatedInt32OrUnsignedOrEnum(strField, index, &ret))
|
2013-03-16 18:31:35 +01:00
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadFloat(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
float ret;
|
2013-03-16 18:31:35 +01:00
|
|
|
|
|
|
|
int index = params[0] >= 3 ? params[3] : -1;
|
|
|
|
if (index < 0)
|
|
|
|
{
|
|
|
|
if (!msg->GetFloatOrDouble(strField, &ret))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:35 +01:00
|
|
|
if (!msg->GetRepeatedFloatOrDouble(strField, index, &ret))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return sp_ftoc(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadBool(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
bool ret;
|
2013-03-16 18:31:35 +01:00
|
|
|
|
|
|
|
int index = params[0] >= 3 ? params[3] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:35 +01:00
|
|
|
if (!msg->GetBool(strField, &ret))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->GetRepeatedBool(strField, index, &ret))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadString(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
char *buf;
|
|
|
|
pCtx->LocalToPhysAddr(params[3], (cell_t **)&buf);
|
|
|
|
|
2013-03-16 18:31:35 +01:00
|
|
|
int index = params[0] >= 5 ? params[5] : -1;
|
|
|
|
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:35 +01:00
|
|
|
if (!msg->GetString(strField, buf, params[4]))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->GetRepeatedString(strField, index, buf, params[4]))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadColor(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *out;
|
|
|
|
pCtx->LocalToPhysAddr(params[3], &out);
|
|
|
|
|
|
|
|
Color clr;
|
2013-03-16 18:31:35 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:35 +01:00
|
|
|
if (!msg->GetColor(strField, &clr))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->GetRepeatedColor(strField, index, &clr))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
out[0] = clr.r();
|
|
|
|
out[1] = clr.g();
|
|
|
|
out[2] = clr.b();
|
|
|
|
out[3] = clr.a();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadAngle(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *out;
|
|
|
|
pCtx->LocalToPhysAddr(params[3], &out);
|
|
|
|
|
|
|
|
QAngle ang;
|
2013-03-16 18:31:35 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
|
|
|
{
|
|
|
|
if (!msg->GetQAngle(strField, &ang))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:35 +01:00
|
|
|
if (!msg->GetRepeatedQAngle(strField, index, &ang))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
out[0] = sp_ftoc(ang.x);
|
|
|
|
out[1] = sp_ftoc(ang.y);
|
|
|
|
out[2] = sp_ftoc(ang.z);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadVector(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *out;
|
|
|
|
pCtx->LocalToPhysAddr(params[3], &out);
|
|
|
|
|
|
|
|
Vector vec;
|
2013-03-16 18:31:35 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
|
|
|
{
|
|
|
|
if (!msg->GetVector(strField, &vec))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:35 +01:00
|
|
|
if (!msg->GetRepeatedVector(strField, index, &vec))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
out[0] = sp_ftoc(vec.x);
|
|
|
|
out[1] = sp_ftoc(vec.y);
|
|
|
|
out[2] = sp_ftoc(vec.z);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadVector2D(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *out;
|
|
|
|
pCtx->LocalToPhysAddr(params[3], &out);
|
|
|
|
|
|
|
|
Vector2D vec;
|
2013-03-16 18:31:35 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
|
|
|
{
|
|
|
|
if (!msg->GetVector2D(strField, &vec))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:35 +01:00
|
|
|
if (!msg->GetRepeatedVector2D(strField, index, &vec))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
out[0] = sp_ftoc(vec.x);
|
|
|
|
out[1] = sp_ftoc(vec.y);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbGetRepeatedFieldCount(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
int cnt = msg->GetRepeatedFieldCount(strField);
|
|
|
|
if (cnt == -1)
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return cnt;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
2013-03-16 18:31:56 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-04-16 17:33:36 +02:00
|
|
|
if (!msg->SetInt32OrUnsignedOrEnum(strField, params[3]))
|
2013-03-16 18:31:56 +01:00
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-04-16 17:33:36 +02:00
|
|
|
if (!msg->SetRepeatedInt32OrUnsignedOrEnum(strField, index, params[3]))
|
2013-03-16 18:31:56 +01:00
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbSetFloat(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
2013-03-16 18:31:56 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:56 +01:00
|
|
|
if (!msg->SetFloatOrDouble(strField, sp_ctof(params[3])))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->SetRepeatedFloatOrDouble(strField, index, sp_ctof(params[3])))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbSetBool(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
bool value = (params[3] == 0 ? false : true);
|
2013-03-16 18:31:56 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:56 +01:00
|
|
|
if (!msg->SetBool(strField, value))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->SetRepeatedBool(strField, index, value))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbSetString(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
char *strValue;
|
|
|
|
if ((err=pCtx->LocalToString(params[3], &strValue)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-03-16 18:31:56 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:56 +01:00
|
|
|
if (!msg->SetString(strField, strValue))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->SetRepeatedString(strField, index, strValue))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbSetColor(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *clrParams;
|
|
|
|
if ((err=pCtx->LocalToPhysAddr(params[3], &clrParams)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Color clr(
|
|
|
|
clrParams[0],
|
|
|
|
clrParams[1],
|
|
|
|
clrParams[2],
|
|
|
|
clrParams[3]);
|
|
|
|
|
2013-03-16 18:31:56 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:56 +01:00
|
|
|
if (!msg->SetColor(strField, clr))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->SetRepeatedColor(strField, index, clr))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbSetAngle(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *angParams;
|
|
|
|
if ((err=pCtx->LocalToPhysAddr(params[3], &angParams)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
QAngle ang(
|
|
|
|
sp_ctof(angParams[0]),
|
|
|
|
sp_ctof(angParams[1]),
|
|
|
|
sp_ctof(angParams[2]));
|
|
|
|
|
2013-03-16 18:31:56 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:56 +01:00
|
|
|
if (!msg->SetQAngle(strField, ang))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->SetRepeatedQAngle(strField, index, ang))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbSetVector(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *vecParams;
|
|
|
|
if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector vec(
|
|
|
|
sp_ctof(vecParams[0]),
|
|
|
|
sp_ctof(vecParams[1]),
|
|
|
|
sp_ctof(vecParams[2]));
|
|
|
|
|
2013-03-16 18:31:56 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:56 +01:00
|
|
|
if (!msg->SetVector(strField, vec))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->SetRepeatedVector(strField, index, vec))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbSetVector2D(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *vecParams;
|
|
|
|
if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector2D vec(
|
|
|
|
sp_ctof(vecParams[0]),
|
|
|
|
sp_ctof(vecParams[1]));
|
|
|
|
|
2013-03-16 18:31:56 +01:00
|
|
|
int index = params[0] >= 4 ? params[4] : -1;
|
|
|
|
if (index < 0)
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-03-16 18:31:56 +01:00
|
|
|
if (!msg->SetVector2D(strField, vec))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!msg->SetRepeatedVector2D(strField, index, vec))
|
|
|
|
{
|
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
|
|
|
|
}
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbAddInt(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
2013-04-16 17:33:36 +02:00
|
|
|
if (!msg->AddInt32OrUnsignedOrEnum(strField, params[3]))
|
2013-01-23 03:43:12 +01:00
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbAddFloat(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
if (!msg->AddFloatOrDouble(strField, sp_ctof(params[3])))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbAddBool(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
bool value = (params[3] == 0 ? false : true);
|
|
|
|
if (!msg->AddBool(strField, value))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbAddString(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
char *strValue;
|
|
|
|
if ((err=pCtx->LocalToString(params[3], &strValue)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!msg->AddString(strField, strValue))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbAddColor(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *clrParams;
|
|
|
|
if ((err=pCtx->LocalToPhysAddr(params[3], &clrParams)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Color clr(
|
|
|
|
clrParams[0],
|
|
|
|
clrParams[1],
|
|
|
|
clrParams[2],
|
|
|
|
clrParams[3]);
|
|
|
|
|
|
|
|
if (!msg->AddColor(strField, clr))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbAddAngle(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *angParams;
|
|
|
|
if ((err=pCtx->LocalToPhysAddr(params[3], &angParams)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
QAngle ang(
|
|
|
|
sp_ctof(angParams[0]),
|
|
|
|
sp_ctof(angParams[1]),
|
|
|
|
sp_ctof(angParams[2]));
|
|
|
|
|
|
|
|
if (!msg->AddQAngle(strField, ang))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbAddVector(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *vecParams;
|
|
|
|
if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector vec(
|
|
|
|
sp_ctof(vecParams[0]),
|
|
|
|
sp_ctof(vecParams[1]),
|
|
|
|
sp_ctof(vecParams[2]));
|
|
|
|
|
|
|
|
if (!msg->AddVector(strField, vec))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbAddVector2D(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
cell_t *vecParams;
|
|
|
|
if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
|
|
|
|
{
|
|
|
|
pCtx->ThrowNativeErrorEx(err, NULL);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Vector2D vec(
|
|
|
|
sp_ctof(vecParams[0]),
|
|
|
|
sp_ctof(vecParams[1]));
|
|
|
|
|
|
|
|
if (!msg->AddVector2D(strField, vec))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadMessage(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
protobuf::Message *innerMsg;
|
|
|
|
if (!msg->GetMessage(strField, &innerMsg))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
2013-03-29 19:37:29 +01:00
|
|
|
Handle_t outHndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
|
2013-01-23 03:43:12 +01:00
|
|
|
msg->AddChildHandle(outHndl);
|
|
|
|
|
|
|
|
return outHndl;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbReadRepeatedMessage(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
const protobuf::Message *innerMsg;
|
|
|
|
if (!msg->GetRepeatedMessage(strField, params[3], &innerMsg))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
2013-03-29 19:37:29 +01:00
|
|
|
Handle_t outHndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(const_cast<protobuf::Message *>(innerMsg)), NULL, g_pCoreIdent, NULL);
|
2013-01-23 03:43:12 +01:00
|
|
|
msg->AddChildHandle(outHndl);
|
|
|
|
|
|
|
|
return outHndl;
|
|
|
|
}
|
|
|
|
|
|
|
|
static cell_t smn_PbAddMessage(IPluginContext *pCtx, const cell_t *params)
|
|
|
|
{
|
|
|
|
GET_MSG_FROM_HANDLE_OR_ERR();
|
|
|
|
GET_FIELD_NAME_OR_ERR();
|
|
|
|
|
|
|
|
protobuf::Message *innerMsg;
|
|
|
|
if (!msg->AddMessage(strField, &innerMsg))
|
|
|
|
{
|
2013-01-23 04:36:38 +01:00
|
|
|
return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
|
2013-01-23 03:43:12 +01:00
|
|
|
}
|
|
|
|
|
2013-03-29 19:37:29 +01:00
|
|
|
Handle_t outHndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
|
2013-01-23 03:43:12 +01:00
|
|
|
msg->AddChildHandle(outHndl);
|
|
|
|
|
|
|
|
return outHndl;
|
|
|
|
}
|
|
|
|
|
|
|
|
REGISTER_NATIVES(protobufnatives)
|
|
|
|
{
|
|
|
|
{"PbReadInt", smn_PbReadInt},
|
|
|
|
{"PbReadFloat", smn_PbReadFloat},
|
|
|
|
{"PbReadBool", smn_PbReadBool},
|
|
|
|
{"PbReadString", smn_PbReadString},
|
|
|
|
{"PbReadColor", smn_PbReadColor},
|
|
|
|
{"PbReadAngle", smn_PbReadAngle},
|
|
|
|
{"PbReadVector", smn_PbReadVector},
|
|
|
|
{"PbReadVector2D", smn_PbReadVector2D},
|
|
|
|
{"PbGetRepeatedFieldCount", smn_PbGetRepeatedFieldCount},
|
|
|
|
{"PbSetInt", smn_PbSetInt},
|
|
|
|
{"PbSetFloat", smn_PbSetFloat},
|
|
|
|
{"PbSetBool", smn_PbSetBool},
|
|
|
|
{"PbSetString", smn_PbSetString},
|
|
|
|
{"PbSetColor", smn_PbSetColor},
|
|
|
|
{"PbSetAngle", smn_PbSetAngle},
|
|
|
|
{"PbSetVector", smn_PbSetVector},
|
|
|
|
{"PbSetVector2D", smn_PbSetVector2D},
|
|
|
|
{"PbAddInt", smn_PbAddInt},
|
|
|
|
{"PbAddFloat", smn_PbAddFloat},
|
|
|
|
{"PbAddBool", smn_PbAddBool},
|
|
|
|
{"PbAddString", smn_PbAddString},
|
|
|
|
{"PbAddColor", smn_PbAddColor},
|
|
|
|
{"PbAddAngle", smn_PbAddAngle},
|
|
|
|
{"PbAddVector", smn_PbAddVector},
|
|
|
|
{"PbAddVector2D", smn_PbAddVector2D},
|
|
|
|
{"PbReadMessage", smn_PbReadMessage},
|
|
|
|
{"PbReadRepeatedMessage", smn_PbReadRepeatedMessage},
|
|
|
|
{"PbAddMessage", smn_PbAddMessage},
|
|
|
|
{NULL, NULL}
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
@@@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@@@@
|
|
|
|
@@@@@@@@ @@@@@@@@@@@@@
|
|
|
|
@@@@@@@@ @@@@@@@@@@@@@
|
|
|
|
@@@@@@ @@@@@@@@@@@@@@@
|
|
|
|
0000 @@@@@@@@@@@@@@@@@@@@@
|
|
|
|
000000000 @@@@@@@@@@@@@@@@@@@
|
|
|
|
0000000000000000000 @@@@@@@@@@@@@@@
|
|
|
|
00000000000000000000 @@@@@@@@@@@@@@@
|
|
|
|
000000000 @@@@@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@ @@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@ @@@@@@@
|
|
|
|
@@@ @@@@ @@@ @@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@ @@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@ @@@@@@@@ @@ @@@@@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@ @@@ @@@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@ @@@@@ @@@@@@
|
|
|
|
@@@@@@@@@ @@@@@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@ @@ @@@@@ @@@@@@@@
|
|
|
|
@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@ @@@@@@ @@@@ @@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@ @@@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@@@ @@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@ @ @@@@@
|
|
|
|
@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@ @@@@ ////
|
|
|
|
//////////// @@@@@@@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@@@ @@ @@@@@@@@@ @@@@ //// ////////////
|
|
|
|
///////////////// /// @@@@@ @@@@ @@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@@ ///// /////// /////////
|
|
|
|
///////////////////// ///// @@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@ @@@@@@@ @ @@@@ ////// /////// ///////////////
|
|
|
|
///////////////////////// /////// @@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@@ @@@@ ////// //////// ////////////////////
|
|
|
|
//////////////////////////// ////////// @@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@ @@@ ////// ////////// ////////////////////////
|
|
|
|
//////////////////// ////////// /////////// @@@@@@@@@@@@@@@@@ @@@@@@@@ @@@ @@@@@@ ////// //////////// //////////////////////////
|
|
|
|
//////////////////// //////////// /////////// @@@@@@@@@@@@@@@@ @@@@ ///////////////////// /////////////////////////////
|
|
|
|
///////////////////// ////////////// ////// @@@@@@@@@ ///////////////////////////////////////////////////////////
|
|
|
|
//////////////////// ///////////////////////////////////// ///////////////////////////////////////////////////////////////////////
|
|
|
|
///////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
*/
|