core/smn_protobuf.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Mon Apr 15 07:12:52 2013 -0400 (2013-04-15)
changeset 3893 87d9d7c50f73
parent 3875 68d82718dc99
child 3895 dc3a6be3a306
permissions -rw-r--r--
Fixed regression in cset 68d82718dc99 causing missing protobuf natives (bug 5712).
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod
     5  * Copyright (C) 2013 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     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.
    11  * 
    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
    15  * details.
    16  *
    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/>.
    19  *
    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>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #include "logic_bridge.h"
    33 #include "UserMessagePBHelpers.h"
    34 #include "smn_usermsgs.h"
    35 
    36 // Assumes pbuf message handle is param 1, gets message as msg
    37 #define GET_MSG_FROM_HANDLE_OR_ERR()                  \
    38 	Handle_t hndl = static_cast<Handle_t>(params[1]); \
    39 	HandleError herr;                                 \
    40 	HandleSecurity sec;                               \
    41 	SMProtobufMessage *msg;                           \
    42 	                                                  \
    43 	sec.pOwner = NULL;                                \
    44 	sec.pIdentity = g_pCoreIdent;                     \
    45 	                                                  \
    46 	if ((herr=handlesys->ReadHandle(hndl, g_ProtobufType, &sec, (void **)&msg)) \
    47 		!= HandleError_None)                          \
    48 	{                                                 \
    49 		return pCtx->ThrowNativeError("Invalid protobuf message handle %x (error %d)", hndl, herr); \
    50 	}
    51 
    52 // Assumes message field name is param 2, gets as strField
    53 #define GET_FIELD_NAME_OR_ERR()                                           \
    54 	int err;                                                              \
    55 	char *strField;                                                       \
    56 	if ((err=pCtx->LocalToString(params[2], &strField)) != SP_ERROR_NONE) \
    57 	{                                                                     \
    58 		pCtx->ThrowNativeErrorEx(err, NULL);                              \
    59 		return 0;                                                         \
    60 	}
    61 
    62 static cell_t smn_PbReadInt(IPluginContext *pCtx, const cell_t *params)
    63 {
    64 	GET_MSG_FROM_HANDLE_OR_ERR();
    65 	GET_FIELD_NAME_OR_ERR();
    66 
    67 	int ret;
    68 
    69 	int index = params[0] >= 3 ? params[3] : -1;
    70 	if (index < 0)
    71 	{
    72 		if (!msg->GetInt32OrUnsigned(strField, &ret))
    73 		{
    74 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
    75 		}
    76 	}
    77 	else
    78 	{
    79 		if (!msg->GetRepeatedInt32OrUnsigned(strField, index, &ret))
    80 		{
    81 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
    82 		}
    83 	}
    84 
    85 	return ret;
    86 }
    87 
    88 static cell_t smn_PbReadFloat(IPluginContext *pCtx, const cell_t *params)
    89 {
    90 	GET_MSG_FROM_HANDLE_OR_ERR();
    91 	GET_FIELD_NAME_OR_ERR();
    92 
    93 	float ret;
    94 
    95 	int index = params[0] >= 3 ? params[3] : -1;
    96 	if (index < 0)
    97 	{
    98 		if (!msg->GetFloatOrDouble(strField, &ret))
    99 		{
   100 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   101 		}
   102 	}
   103 	else
   104 	{
   105 		if (!msg->GetRepeatedFloatOrDouble(strField, index, &ret))
   106 		{
   107 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   108 		}
   109 	}
   110 
   111 	return sp_ftoc(ret);
   112 }
   113 
   114 static cell_t smn_PbReadBool(IPluginContext *pCtx, const cell_t *params)
   115 {
   116 	GET_MSG_FROM_HANDLE_OR_ERR();
   117 	GET_FIELD_NAME_OR_ERR();
   118 
   119 	bool ret;
   120 
   121 	int index = params[0] >= 3 ? params[3] : -1;
   122 	if (index < 0)
   123 	{
   124 		if (!msg->GetBool(strField, &ret))
   125 		{
   126 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   127 		}
   128 	}
   129 	else
   130 	{
   131 		if (!msg->GetRepeatedBool(strField, index, &ret))
   132 		{
   133 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   134 		} 
   135 	}
   136 
   137 	return ret ? 1 : 0;
   138 }
   139 
   140 static cell_t smn_PbReadString(IPluginContext *pCtx, const cell_t *params)
   141 {
   142 	GET_MSG_FROM_HANDLE_OR_ERR();
   143 	GET_FIELD_NAME_OR_ERR();
   144 
   145 	char *buf;
   146 	pCtx->LocalToPhysAddr(params[3], (cell_t **)&buf);
   147 
   148 	int index = params[0] >= 5 ? params[5] : -1;
   149 
   150 	if (index < 0)
   151 	{
   152 		if (!msg->GetString(strField, buf, params[4]))
   153 		{
   154 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   155 		}
   156 	}
   157 	else
   158 	{
   159 		if (!msg->GetRepeatedString(strField, index, buf, params[4]))
   160 		{
   161 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   162 		}
   163 	}
   164 
   165 	return 1;
   166 }
   167 
   168 static cell_t smn_PbReadColor(IPluginContext *pCtx, const cell_t *params)
   169 {
   170 	GET_MSG_FROM_HANDLE_OR_ERR();
   171 	GET_FIELD_NAME_OR_ERR();
   172 
   173 	cell_t *out;
   174 	pCtx->LocalToPhysAddr(params[3], &out);
   175 
   176 	Color clr;
   177 	int index = params[0] >= 4 ? params[4] : -1;
   178 	if (index < 0)
   179 	{
   180 		if (!msg->GetColor(strField, &clr))
   181 		{
   182 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   183 		}
   184 	}
   185 	else
   186 	{
   187 		if (!msg->GetRepeatedColor(strField, index, &clr))
   188 		{
   189 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   190 		}
   191 	}
   192 
   193 	out[0] = clr.r();
   194 	out[1] = clr.g();
   195 	out[2] = clr.b();
   196 	out[3] = clr.a();
   197 
   198 	return 1;
   199 }
   200 
   201 static cell_t smn_PbReadAngle(IPluginContext *pCtx, const cell_t *params)
   202 {
   203 	GET_MSG_FROM_HANDLE_OR_ERR();
   204 	GET_FIELD_NAME_OR_ERR();
   205 
   206 	cell_t *out;
   207 	pCtx->LocalToPhysAddr(params[3], &out);
   208 
   209 	QAngle ang;
   210 	int index = params[0] >= 4 ? params[4] : -1;
   211 	if (index < 0)
   212 	{
   213 		if (!msg->GetQAngle(strField, &ang))
   214 		{
   215 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   216 		}
   217 	}
   218 	else
   219 	{
   220 		if (!msg->GetRepeatedQAngle(strField, index, &ang))
   221 		{
   222 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   223 		}
   224 	}
   225 
   226 	out[0] = sp_ftoc(ang.x);
   227 	out[1] = sp_ftoc(ang.y);
   228 	out[2] = sp_ftoc(ang.z);
   229 
   230 	return 1;
   231 }
   232 
   233 static cell_t smn_PbReadVector(IPluginContext *pCtx, const cell_t *params)
   234 {
   235 	GET_MSG_FROM_HANDLE_OR_ERR();
   236 	GET_FIELD_NAME_OR_ERR();
   237 
   238 	cell_t *out;
   239 	pCtx->LocalToPhysAddr(params[3], &out);
   240 
   241 	Vector vec;
   242 	int index = params[0] >= 4 ? params[4] : -1;
   243 	if (index < 0)
   244 	{
   245 		if (!msg->GetVector(strField, &vec))
   246 		{
   247 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   248 		}
   249 	}
   250 	else
   251 	{
   252 		if (!msg->GetRepeatedVector(strField, index, &vec))
   253 		{
   254 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   255 		}
   256 	}
   257 
   258 	out[0] = sp_ftoc(vec.x);
   259 	out[1] = sp_ftoc(vec.y);
   260 	out[2] = sp_ftoc(vec.z);
   261 
   262 	return 1;
   263 }
   264 
   265 static cell_t smn_PbReadVector2D(IPluginContext *pCtx, const cell_t *params)
   266 {
   267 	GET_MSG_FROM_HANDLE_OR_ERR();
   268 	GET_FIELD_NAME_OR_ERR();
   269 
   270 	cell_t *out;
   271 	pCtx->LocalToPhysAddr(params[3], &out);
   272 
   273 	Vector2D vec;
   274 	int index = params[0] >= 4 ? params[4] : -1;
   275 	if (index < 0)
   276 	{
   277 		if (!msg->GetVector2D(strField, &vec))
   278 		{
   279 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   280 		}
   281 	}
   282 	else
   283 	{
   284 		if (!msg->GetRepeatedVector2D(strField, index, &vec))
   285 		{
   286 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   287 		}
   288 	}
   289 
   290 	out[0] = sp_ftoc(vec.x);
   291 	out[1] = sp_ftoc(vec.y);
   292 
   293 	return 1;
   294 }
   295 
   296 static cell_t smn_PbGetRepeatedFieldCount(IPluginContext *pCtx, const cell_t *params)
   297 {
   298 	GET_MSG_FROM_HANDLE_OR_ERR();
   299 	GET_FIELD_NAME_OR_ERR();
   300 
   301 	int cnt = msg->GetRepeatedFieldCount(strField);
   302 	if (cnt == -1)
   303 	{
   304 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   305 	}
   306 
   307 	return cnt;
   308 }
   309 
   310 static cell_t smn_PbReadRepeatedInt(IPluginContext *pCtx, const cell_t *params)
   311 {
   312 	GET_MSG_FROM_HANDLE_OR_ERR();
   313 	GET_FIELD_NAME_OR_ERR();
   314 
   315 	int ret;
   316 	if (!msg->GetRepeatedInt32OrUnsigned(strField, params[3], &ret))
   317 	{
   318 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   319 	}
   320 
   321 	return ret;
   322 }
   323 
   324 static cell_t smn_PbReadRepeatedFloat(IPluginContext *pCtx, const cell_t *params)
   325 {
   326 	GET_MSG_FROM_HANDLE_OR_ERR();
   327 	GET_FIELD_NAME_OR_ERR();
   328 
   329 	float ret;
   330 	if (!msg->GetRepeatedFloatOrDouble(strField, params[3], &ret))
   331 	{
   332 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   333 	}
   334 
   335 	return sp_ftoc(ret);
   336 }
   337 
   338 static cell_t smn_PbReadRepeatedBool(IPluginContext *pCtx, const cell_t *params)
   339 {
   340 	GET_MSG_FROM_HANDLE_OR_ERR();
   341 	GET_FIELD_NAME_OR_ERR();
   342 
   343 	bool ret;
   344 	if (!msg->GetRepeatedBool(strField, params[3], &ret))
   345 	{
   346 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   347 	}
   348 
   349 	return ret ? 1 : 0;
   350 }
   351 
   352 static cell_t smn_PbReadRepeatedString(IPluginContext *pCtx, const cell_t *params)
   353 {
   354 	GET_MSG_FROM_HANDLE_OR_ERR();
   355 	GET_FIELD_NAME_OR_ERR();
   356 
   357 	char *buf;
   358 	pCtx->LocalToPhysAddr(params[4], (cell_t **)&buf);
   359 
   360 	if (!msg->GetRepeatedString(strField, params[3], buf, params[5]))
   361 	{
   362 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   363 	}
   364 
   365 	return 1;
   366 }
   367 
   368 static cell_t smn_PbReadRepeatedColor(IPluginContext *pCtx, const cell_t *params)
   369 {
   370 	GET_MSG_FROM_HANDLE_OR_ERR();
   371 	GET_FIELD_NAME_OR_ERR();
   372 
   373 	cell_t *out;
   374 	pCtx->LocalToPhysAddr(params[4], &out);
   375 
   376 	Color clr;
   377 	if (!msg->GetRepeatedColor(strField, params[3], &clr))
   378 	{
   379 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   380 	}
   381 
   382 	out[0] = clr.r();
   383 	out[1] = clr.g();
   384 	out[2] = clr.b();
   385 	out[3] = clr.a();
   386 
   387 	return 1;
   388 }
   389 
   390 static cell_t smn_PbReadRepeatedAngle(IPluginContext *pCtx, const cell_t *params)
   391 {
   392 	GET_MSG_FROM_HANDLE_OR_ERR();
   393 	GET_FIELD_NAME_OR_ERR();
   394 
   395 	cell_t *out;
   396 	pCtx->LocalToPhysAddr(params[4], &out);
   397 
   398 	QAngle ang;
   399 	if (!msg->GetRepeatedQAngle(strField, params[3], &ang))
   400 	{
   401 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   402 	}
   403 
   404 	out[0] = sp_ftoc(ang.x);
   405 	out[1] = sp_ftoc(ang.y);
   406 	out[2] = sp_ftoc(ang.z);
   407 
   408 	return 1;
   409 }
   410 
   411 static cell_t smn_PbReadRepeatedVector(IPluginContext *pCtx, const cell_t *params)
   412 {
   413 	GET_MSG_FROM_HANDLE_OR_ERR();
   414 	GET_FIELD_NAME_OR_ERR();
   415 
   416 	cell_t *out;
   417 	pCtx->LocalToPhysAddr(params[4], &out);
   418 
   419 	Vector vec;
   420 	if (!msg->GetRepeatedVector(strField, params[3], &vec))
   421 	{
   422 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   423 	}
   424 
   425 	out[0] = sp_ftoc(vec.x);
   426 	out[1] = sp_ftoc(vec.y);
   427 	out[2] = sp_ftoc(vec.z);
   428 
   429 	return 1;
   430 }
   431 
   432 static cell_t smn_PbReadRepeatedVector2D(IPluginContext *pCtx, const cell_t *params)
   433 {
   434 	GET_MSG_FROM_HANDLE_OR_ERR();
   435 	GET_FIELD_NAME_OR_ERR();
   436 
   437 	cell_t *out;
   438 	pCtx->LocalToPhysAddr(params[4], &out);
   439 
   440 	Vector2D vec;
   441 	if (!msg->GetRepeatedVector2D(strField, params[3], &vec))
   442 	{
   443 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   444 	}
   445 
   446 	out[0] = sp_ftoc(vec.x);
   447 	out[1] = sp_ftoc(vec.y);
   448 
   449 	return 1;
   450 }
   451 
   452 static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params)
   453 {
   454 	GET_MSG_FROM_HANDLE_OR_ERR();
   455 	GET_FIELD_NAME_OR_ERR();
   456 
   457 	int index = params[0] >= 4 ? params[4] : -1;
   458 	if (index < 0)
   459 	{
   460 		if (!msg->SetInt32OrUnsigned(strField, params[3]))
   461 		{
   462 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   463 		}
   464 	}
   465 	else
   466 	{
   467 		if (!msg->SetRepeatedInt32OrUnsigned(strField, index, params[3]))
   468 		{
   469 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   470 		}
   471 	}
   472 
   473 	return 1;
   474 }
   475 
   476 static cell_t smn_PbSetFloat(IPluginContext *pCtx, const cell_t *params)
   477 {
   478 	GET_MSG_FROM_HANDLE_OR_ERR();
   479 	GET_FIELD_NAME_OR_ERR();
   480 
   481 	int index = params[0] >= 4 ? params[4] : -1;
   482 	if (index < 0)
   483 	{
   484 		if (!msg->SetFloatOrDouble(strField, sp_ctof(params[3])))
   485 		{
   486 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   487 		}
   488 	}
   489 	else
   490 	{
   491 		if (!msg->SetRepeatedFloatOrDouble(strField, index, sp_ctof(params[3])))
   492 		{
   493 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   494 		}
   495 	}
   496 
   497 	return 1;
   498 }
   499 
   500 static cell_t smn_PbSetBool(IPluginContext *pCtx, const cell_t *params)
   501 {
   502 	GET_MSG_FROM_HANDLE_OR_ERR();
   503 	GET_FIELD_NAME_OR_ERR();
   504 
   505 	bool value = (params[3] == 0 ? false : true);
   506 	int index = params[0] >= 4 ? params[4] : -1;
   507 	if (index < 0)
   508 	{
   509 		if (!msg->SetBool(strField, value))
   510 		{
   511 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   512 		}
   513 	}
   514 	else
   515 	{
   516 		if (!msg->SetRepeatedBool(strField, index, value))
   517 		{
   518 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   519 		}
   520 	}
   521 
   522 	return 1;
   523 }
   524 
   525 static cell_t smn_PbSetString(IPluginContext *pCtx, const cell_t *params)
   526 {
   527 	GET_MSG_FROM_HANDLE_OR_ERR();
   528 	GET_FIELD_NAME_OR_ERR();
   529 
   530 	char *strValue;
   531 	if ((err=pCtx->LocalToString(params[3], &strValue)) != SP_ERROR_NONE)
   532 	{
   533 		pCtx->ThrowNativeErrorEx(err, NULL);
   534 		return 0;
   535 	}
   536 
   537 	int index = params[0] >= 4 ? params[4] : -1;
   538 	if (index < 0)
   539 	{
   540 		if (!msg->SetString(strField, strValue))
   541 		{
   542 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   543 		}
   544 	}
   545 	else
   546 	{
   547 		if (!msg->SetRepeatedString(strField, index, strValue))
   548 		{
   549 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   550 		}
   551 	}
   552 
   553 	return 1;
   554 }
   555 
   556 static cell_t smn_PbSetColor(IPluginContext *pCtx, const cell_t *params)
   557 {
   558 	GET_MSG_FROM_HANDLE_OR_ERR();
   559 	GET_FIELD_NAME_OR_ERR();
   560 
   561 	cell_t *clrParams;
   562 	if ((err=pCtx->LocalToPhysAddr(params[3], &clrParams)) != SP_ERROR_NONE)
   563 	{
   564 		pCtx->ThrowNativeErrorEx(err, NULL);
   565 		return 0;
   566 	}
   567 
   568 	Color clr(
   569 		clrParams[0],
   570 		clrParams[1],
   571 		clrParams[2],
   572 		clrParams[3]);
   573 
   574 	int index = params[0] >= 4 ? params[4] : -1;
   575 	if (index < 0)
   576 	{
   577 		if (!msg->SetColor(strField, clr))
   578 		{
   579 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   580 		}
   581 	}
   582 	else
   583 	{
   584 		if (!msg->SetRepeatedColor(strField, index, clr))
   585 		{
   586 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   587 		}
   588 	}
   589 
   590 	return 1;
   591 }
   592 
   593 static cell_t smn_PbSetAngle(IPluginContext *pCtx, const cell_t *params)
   594 {
   595 	GET_MSG_FROM_HANDLE_OR_ERR();
   596 	GET_FIELD_NAME_OR_ERR();
   597 
   598 	cell_t *angParams;
   599 	if ((err=pCtx->LocalToPhysAddr(params[3], &angParams)) != SP_ERROR_NONE)
   600 	{
   601 		pCtx->ThrowNativeErrorEx(err, NULL);
   602 		return 0;
   603 	}
   604 
   605 	QAngle ang(
   606 		sp_ctof(angParams[0]),
   607 		sp_ctof(angParams[1]),
   608 		sp_ctof(angParams[2]));
   609 
   610 	int index = params[0] >= 4 ? params[4] : -1;
   611 	if (index < 0)
   612 	{
   613 		if (!msg->SetQAngle(strField, ang))
   614 		{
   615 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   616 		}
   617 	}
   618 	else
   619 	{
   620 		if (!msg->SetRepeatedQAngle(strField, index, ang))
   621 		{
   622 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   623 		}
   624 	}
   625 
   626 	return 1;
   627 }
   628 
   629 static cell_t smn_PbSetVector(IPluginContext *pCtx, const cell_t *params)
   630 {
   631 	GET_MSG_FROM_HANDLE_OR_ERR();
   632 	GET_FIELD_NAME_OR_ERR();
   633 
   634 	cell_t *vecParams;
   635 	if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
   636 	{
   637 		pCtx->ThrowNativeErrorEx(err, NULL);
   638 		return 0;
   639 	}
   640 
   641 	Vector vec(
   642 		sp_ctof(vecParams[0]),
   643 		sp_ctof(vecParams[1]),
   644 		sp_ctof(vecParams[2]));
   645 
   646 	int index = params[0] >= 4 ? params[4] : -1;
   647 	if (index < 0)
   648 	{
   649 		if (!msg->SetVector(strField, vec))
   650 		{
   651 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   652 		}
   653 	}
   654 	else
   655 	{
   656 		if (!msg->SetRepeatedVector(strField, index, vec))
   657 		{
   658 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   659 		}
   660 	}
   661 
   662 	return 1;
   663 }
   664 
   665 static cell_t smn_PbSetVector2D(IPluginContext *pCtx, const cell_t *params)
   666 {
   667 	GET_MSG_FROM_HANDLE_OR_ERR();
   668 	GET_FIELD_NAME_OR_ERR();
   669 
   670 	cell_t *vecParams;
   671 	if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
   672 	{
   673 		pCtx->ThrowNativeErrorEx(err, NULL);
   674 		return 0;
   675 	}
   676 
   677 	Vector2D vec(
   678 		sp_ctof(vecParams[0]),
   679 		sp_ctof(vecParams[1]));
   680 
   681 	int index = params[0] >= 4 ? params[4] : -1;
   682 	if (index < 0)
   683 	{
   684 		if (!msg->SetVector2D(strField, vec))
   685 		{
   686 			return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   687 		}
   688 	}
   689 	else
   690 	{
   691 		if (!msg->SetRepeatedVector2D(strField, index, vec))
   692 		{
   693 			return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, index, msg->GetProtobufMessage()->GetTypeName().c_str());
   694 		}
   695 	}
   696 
   697 	return 1;
   698 }
   699 
   700 static cell_t smn_PbAddInt(IPluginContext *pCtx, const cell_t *params)
   701 {
   702 	GET_MSG_FROM_HANDLE_OR_ERR();
   703 	GET_FIELD_NAME_OR_ERR();
   704 
   705 	if (!msg->AddInt32OrUnsigned(strField, params[3]))
   706 	{
   707 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   708 	}
   709 
   710 	return 1;
   711 }
   712 
   713 static cell_t smn_PbAddFloat(IPluginContext *pCtx, const cell_t *params)
   714 {
   715 	GET_MSG_FROM_HANDLE_OR_ERR();
   716 	GET_FIELD_NAME_OR_ERR();
   717 
   718 	if (!msg->AddFloatOrDouble(strField, sp_ctof(params[3])))
   719 	{
   720 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   721 	}
   722 
   723 	return 1;
   724 }
   725 
   726 static cell_t smn_PbAddBool(IPluginContext *pCtx, const cell_t *params)
   727 {
   728 	GET_MSG_FROM_HANDLE_OR_ERR();
   729 	GET_FIELD_NAME_OR_ERR();
   730 
   731 	bool value = (params[3] == 0 ? false : true);
   732 	if (!msg->AddBool(strField, value))
   733 	{
   734 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   735 	}
   736 
   737 	return 1;
   738 }
   739 
   740 static cell_t smn_PbAddString(IPluginContext *pCtx, const cell_t *params)
   741 {
   742 	GET_MSG_FROM_HANDLE_OR_ERR();
   743 	GET_FIELD_NAME_OR_ERR();
   744 
   745 	char *strValue;
   746 	if ((err=pCtx->LocalToString(params[3], &strValue)) != SP_ERROR_NONE)
   747 	{
   748 		pCtx->ThrowNativeErrorEx(err, NULL);
   749 		return 0;
   750 	}
   751 
   752 	if (!msg->AddString(strField, strValue))
   753 	{
   754 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   755 	}
   756 
   757 	return 1;
   758 }
   759 
   760 static cell_t smn_PbAddColor(IPluginContext *pCtx, const cell_t *params)
   761 {
   762 	GET_MSG_FROM_HANDLE_OR_ERR();
   763 	GET_FIELD_NAME_OR_ERR();
   764 
   765 	cell_t *clrParams;
   766 	if ((err=pCtx->LocalToPhysAddr(params[3], &clrParams)) != SP_ERROR_NONE)
   767 	{
   768 		pCtx->ThrowNativeErrorEx(err, NULL);
   769 		return 0;
   770 	}
   771 
   772 	Color clr(
   773 		clrParams[0],
   774 		clrParams[1],
   775 		clrParams[2],
   776 		clrParams[3]);
   777 
   778 	if (!msg->AddColor(strField, clr))
   779 	{
   780 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   781 	}
   782 
   783 	return 1;
   784 }
   785 
   786 static cell_t smn_PbAddAngle(IPluginContext *pCtx, const cell_t *params)
   787 {
   788 	GET_MSG_FROM_HANDLE_OR_ERR();
   789 	GET_FIELD_NAME_OR_ERR();
   790 
   791 	cell_t *angParams;
   792 	if ((err=pCtx->LocalToPhysAddr(params[3], &angParams)) != SP_ERROR_NONE)
   793 	{
   794 		pCtx->ThrowNativeErrorEx(err, NULL);
   795 		return 0;
   796 	}
   797 
   798 	QAngle ang(
   799 		sp_ctof(angParams[0]),
   800 		sp_ctof(angParams[1]),
   801 		sp_ctof(angParams[2]));
   802 
   803 	if (!msg->AddQAngle(strField, ang))
   804 	{
   805 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   806 	}
   807 
   808 	return 1;
   809 }
   810 
   811 static cell_t smn_PbAddVector(IPluginContext *pCtx, const cell_t *params)
   812 {
   813 	GET_MSG_FROM_HANDLE_OR_ERR();
   814 	GET_FIELD_NAME_OR_ERR();
   815 
   816 	cell_t *vecParams;
   817 	if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
   818 	{
   819 		pCtx->ThrowNativeErrorEx(err, NULL);
   820 		return 0;
   821 	}
   822 
   823 	Vector vec(
   824 		sp_ctof(vecParams[0]),
   825 		sp_ctof(vecParams[1]),
   826 		sp_ctof(vecParams[2]));
   827 
   828 	if (!msg->AddVector(strField, vec))
   829 	{
   830 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   831 	}
   832 
   833 	return 1;
   834 }
   835 
   836 static cell_t smn_PbAddVector2D(IPluginContext *pCtx, const cell_t *params)
   837 {
   838 	GET_MSG_FROM_HANDLE_OR_ERR();
   839 	GET_FIELD_NAME_OR_ERR();
   840 
   841 	cell_t *vecParams;
   842 	if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
   843 	{
   844 		pCtx->ThrowNativeErrorEx(err, NULL);
   845 		return 0;
   846 	}
   847 
   848 	Vector2D vec(
   849 		sp_ctof(vecParams[0]),
   850 		sp_ctof(vecParams[1]));
   851 
   852 	if (!msg->AddVector2D(strField, vec))
   853 	{
   854 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   855 	}
   856 
   857 	return 1;
   858 }
   859 
   860 static cell_t smn_PbReadMessage(IPluginContext *pCtx, const cell_t *params)
   861 {
   862 	GET_MSG_FROM_HANDLE_OR_ERR();
   863 	GET_FIELD_NAME_OR_ERR();
   864 
   865 	protobuf::Message *innerMsg;
   866 	if (!msg->GetMessage(strField, &innerMsg))
   867 	{
   868 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   869 	}
   870 
   871 	Handle_t outHndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
   872 	msg->AddChildHandle(outHndl);
   873 
   874 	return outHndl;
   875 }
   876 
   877 static cell_t smn_PbReadRepeatedMessage(IPluginContext *pCtx, const cell_t *params)
   878 {
   879 	GET_MSG_FROM_HANDLE_OR_ERR();
   880 	GET_FIELD_NAME_OR_ERR();
   881 
   882 	const protobuf::Message *innerMsg;
   883 	if (!msg->GetRepeatedMessage(strField, params[3], &innerMsg))
   884 	{
   885 		return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName().c_str());
   886 	}
   887 
   888 	Handle_t outHndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(const_cast<protobuf::Message *>(innerMsg)), NULL, g_pCoreIdent, NULL);
   889 	msg->AddChildHandle(outHndl);
   890 
   891 	return outHndl;
   892 }
   893 
   894 static cell_t smn_PbAddMessage(IPluginContext *pCtx, const cell_t *params)
   895 {
   896 	GET_MSG_FROM_HANDLE_OR_ERR();
   897 	GET_FIELD_NAME_OR_ERR();
   898 
   899 	protobuf::Message *innerMsg;
   900 	if (!msg->AddMessage(strField, &innerMsg))
   901 	{
   902 		return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName().c_str());
   903 	}
   904 
   905 	Handle_t outHndl = handlesys->CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
   906 	msg->AddChildHandle(outHndl);
   907 
   908 	return outHndl;
   909 }
   910 
   911 REGISTER_NATIVES(protobufnatives)
   912 {
   913 	{"PbReadInt",					smn_PbReadInt},
   914 	{"PbReadFloat",					smn_PbReadFloat},
   915 	{"PbReadBool",					smn_PbReadBool},
   916 	{"PbReadString",				smn_PbReadString},
   917 	{"PbReadColor",					smn_PbReadColor},
   918 	{"PbReadAngle",					smn_PbReadAngle},
   919 	{"PbReadVector",				smn_PbReadVector},
   920 	{"PbReadVector2D",				smn_PbReadVector2D},
   921 	{"PbGetRepeatedFieldCount",		smn_PbGetRepeatedFieldCount},
   922 	{"PbReadRepeatedInt",			smn_PbReadRepeatedInt},
   923 	{"PbReadRepeatedFloat",			smn_PbReadRepeatedFloat},
   924 	{"PbReadRepeatedBool",			smn_PbReadRepeatedBool},
   925 	{"PbReadRepeatedString",		smn_PbReadRepeatedString},
   926 	{"PbReadRepeatedColor",			smn_PbReadRepeatedColor},
   927 	{"PbReadRepeatedAngle",			smn_PbReadRepeatedAngle},
   928 	{"PbReadRepeatedVector",		smn_PbReadRepeatedVector},
   929 	{"PbReadRepeatedVector2D",		smn_PbReadRepeatedVector2D},
   930 	{"PbSetInt",					smn_PbSetInt},
   931 	{"PbSetFloat",					smn_PbSetFloat},
   932 	{"PbSetBool",					smn_PbSetBool},
   933 	{"PbSetString",					smn_PbSetString},
   934 	{"PbSetColor",					smn_PbSetColor},
   935 	{"PbSetAngle",					smn_PbSetAngle},
   936 	{"PbSetVector",					smn_PbSetVector},
   937 	{"PbSetVector2D",				smn_PbSetVector2D},
   938 	{"PbAddInt",					smn_PbAddInt},
   939 	{"PbAddFloat",					smn_PbAddFloat},
   940 	{"PbAddBool",					smn_PbAddBool},
   941 	{"PbAddString",					smn_PbAddString},
   942 	{"PbAddColor",					smn_PbAddColor},
   943 	{"PbAddAngle",					smn_PbAddAngle},
   944 	{"PbAddVector",					smn_PbAddVector},
   945 	{"PbAddVector2D",				smn_PbAddVector2D},
   946 	{"PbReadMessage",				smn_PbReadMessage},
   947 	{"PbReadRepeatedMessage",		smn_PbReadRepeatedMessage},
   948 	{"PbAddMessage",				smn_PbAddMessage},
   949 	{NULL,							NULL}
   950 };
   951 
   952 /*
   953                                        @@@@@@@@@@@@@ 
   954                                      @@@@@@@@@@@@@@@@@@
   955                                      @@@@@@@@@@@@@@@@@@@@@      
   956                                     @@@@@@@@@@@@@@@@@@@@@@@@               
   957                                    @@@@@@@@    @@@@@@@@@@@@@
   958                                    @@@@@@@@    @@@@@@@@@@@@@          
   959                                       @@@@@@  @@@@@@@@@@@@@@@             
   960                                  0000   @@@@@@@@@@@@@@@@@@@@@                
   961                               000000000   @@@@@@@@@@@@@@@@@@@           
   962                        0000000000000000000   @@@@@@@@@@@@@@@          
   963                        00000000000000000000  @@@@@@@@@@@@@@@            
   964                             000000000       @@@@@@@@@@@@@@@           
   965                                          @@@@@@@@@@@@@@@@@               
   966                                         @@@@@@@@@@@@@@@@@@      
   967                                        @@@@@@@@@@@@@@@@@@       
   968                                        @@@@@@@@@@@@@@@@@@                                                                @@@@
   969                                       @@@@@@@@@@@@@@@@@@@                                                             @@@@@@@  
   970                                      @@@   @@@@    @@@                                                             @@@@@@@@@@     
   971                                     @@@@@@@@@@@@@@@@@@@@@@@@@@                                                 @@@@@@@@@@  @@@@@    
   972                                    @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@   @@@@@@@@                                @@  @@@@@@@@@@@@@@@ 
   973                                   @@@@@@@@@@@@@@@@@@@@@@@@@@ @@   @@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@@@@@  @@  @@@@@@@@@        
   974                                   @@@@@@@@@@@@@@@@@@@@@@@ @@@@   @@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@@@@@@@  @@  @@@@@@@@@@@@@
   975                                   @@@@@@@@@@@@@@@@@@@@@ @@@@    @@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@@@@@@@@@  @@@  @@@@@@@@@@@@     
   976                                  @@@@@@@@@@@@@@@@@@@@ @@@@@@   @@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@   @@@@  @@@@@@@@@@@     
   977                                  @@@@@@@@@@@@@@@@@  @@@@@@    @@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@@@@@@@      @@@@@ @@@@@@      
   978                                  @@@@@@@@@       @@@@@@@@@   @@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@     @@  @@@@@ @@@@@@@@   
   979                                            @@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@   @@@@@@  @@@@  @@@@@@  
   980                                   @@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@@@@@@@@  @@@@@@         @@@@@@  @@@@@@
   981                                  @@@@@@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@@@@@@@@              @@@@@@@@   @@@@
   982                                   @@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@       @@@@@@@@@@@@@@  @  @@@@@  
   983                                    @@@@@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@    @@@@@  @@@@    ////
   984                      ////////////   @@@@@@@@@@@ @@@@@@       @@@@@@@@@@@@@@@@@@@@  @@      @@@@@@@@@  @@@@    //// //////////// 
   985               ///////////////// ///    @@@@@          @@@@    @@@@@@@@@@@@@@@@@@@   @@@@@@@@@@@@@     @@@@   ///// ///////  /////////    
   986         /////////////////////  /////         @@@@@@@@@@@@@@   @@@@@@@@@@@@@@@@@@@   @@@@@@@      @  @@@@    ////// ///////  ///////////////
   987     ///////////////////////// ///////    @@@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@@@@           @@@@@   @@@@    //////  ////////  //////////////////// 
   988  ////////////////////////////  //////////   @@@@@@@@@@@@@@@@@@    @@@@@@@@@@@@   @@@@@@@@@     @@@      //////  ////////// ////////////////////////
   989 //////////////////// //////////  ///////////   @@@@@@@@@@@@@@@@@     @@@@@@@@   @@@      @@@@@@      ////// ////////////  //////////////////////////
   990 //////////////////// ////////////   ///////////   @@@@@@@@@@@@@@@@               @@@@            /////////////////////  /////////////////////////////
   991 /////////////////////  //////////////       //////              @@@@@@@@@                ///////////////////////////////////////////////////////////
   992    ////////////////////    /////////////////////////////////////          ///////////////////////////////////////////////////////////////////////
   993        /////////////////////     ////////////////////////////////////////////////////////////////////////////////////////////////////////////  
   994             ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   995                    //////////////////////////////////////////////////////////////////////////////////////////////////////////////   
   996                              ///////////////////////////////////////////////////////////////////////////////////////// 
   997                                              //////////////////////////////////////////////////////////
   998 */