Added initial support for protobuf usermessages on CS:GO (bug 5579, r=asherkin).
1.1 --- a/AMBuildScript Mon Jan 07 09:09:14 2013 -0500
1.2 +++ b/AMBuildScript Tue Jan 22 21:43:12 2013 -0500
1.3 @@ -124,7 +124,6 @@
1.4 self.compiler.AddToListVar('CFLAGS', '-m32')
1.5 self.compiler.AddToListVar('POSTLINKFLAGS', '-m32')
1.6 self.compiler.AddToListVar('CXXFLAGS', '-fno-exceptions')
1.7 - self.compiler.AddToListVar('CXXFLAGS', '-fno-rtti')
1.8 self.compiler.AddToListVar('CXXFLAGS', '-fno-threadsafe-statics')
1.9 self.compiler.AddToListVar('CXXFLAGS', '-Wno-non-virtual-dtor')
1.10 self.compiler.AddToListVar('CXXFLAGS', '-Wno-overloaded-virtual')
2.1 --- a/core/AMBuilder Mon Jan 07 09:09:14 2013 -0500
2.2 +++ b/core/AMBuilder Tue Jan 22 21:43:12 2013 -0500
2.3 @@ -1,5 +1,6 @@
2.4 # vim: set ts=2 sw=2 tw=99 noet ft=python:
2.5 import os
2.6 +from ambuild.command import SymlinkCommand
2.7
2.8 for i in SM.sdkInfo:
2.9 sdk = SM.sdkInfo[i]
2.10 @@ -10,9 +11,35 @@
2.11
2.12 compiler = SM.DefaultHL2Compiler('core', i)
2.13
2.14 + if i == 'csgo':
2.15 + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache[sdk['sdk']], 'common', 'protobuf-2.3.0', 'src'))
2.16 + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache[sdk['sdk']], 'public', 'engine', 'protobuf'))
2.17 + compiler['CXXINCLUDES'].append(os.path.join(AMBuild.cache[sdk['sdk']], 'public', 'game', 'shared', 'csgo', 'protobuf'))
2.18 +
2.19 extension = AMBuild.AddJob(name)
2.20 binary = Cpp.LibraryBuilder(name, AMBuild, extension, compiler)
2.21 SM.PreSetupHL2Job(extension, binary, i)
2.22 +
2.23 + if i == 'csgo':
2.24 + if AMBuild.target['platform'] == 'linux':
2.25 + link = os.path.join(os.path.join(AMBuild.outputFolder, extension.workFolder), 'libprotobuf.a')
2.26 + target = os.path.join(os.path.join(AMBuild.cache[sdk['sdk']], 'lib', 'linux32', 'release'), 'libprotobuf.a')
2.27 + try:
2.28 + os.lstat(link)
2.29 + except:
2.30 + extension.AddCommand(SymlinkCommand(link, target))
2.31 + elif AMBuild.target['platform'] == 'darwin':
2.32 + link = os.path.join(os.path.join(AMBuild.outputFolder, extension.workFolder), 'libprotobuf.a')
2.33 + target = os.path.join(os.path.join(AMBuild.cache[sdk['sdk']], 'lib', 'osx32', 'release'), 'libprotobuf.a')
2.34 + try:
2.35 + os.lstat(link)
2.36 + except:
2.37 + extension.AddCommand(SymlinkCommand(link, target))
2.38 + elif AMBuild.target['platform'] == 'windows':
2.39 + libPath = os.path.join(AMBuild.cache[sdk['sdk']], 'lib', 'win32', 'release', 'vs2010', 'libprotobuf.lib')
2.40 + binary.RebuildIfNewer(libPath)
2.41 + binary['POSTLINKFLAGS'].append(libPath)
2.42 +
2.43 files = [
2.44 'AdminCache.cpp',
2.45 'ExtensionSys.cpp',
2.46 @@ -49,7 +76,6 @@
2.47 'CoreConfig.cpp',
2.48 'Logger.cpp',
2.49 'PluginInfoDatabase.cpp',
2.50 - 'smn_bitbuffer.cpp',
2.51 'smn_halflife.cpp',
2.52 'PluginSys.cpp',
2.53 'smn_console.cpp',
2.54 @@ -71,7 +97,22 @@
2.55 'sm_srvcmds.cpp',
2.56 'ConsoleDetours.cpp'
2.57 ]
2.58 +
2.59 + if i == 'csgo':
2.60 + files.append('smn_protobuf.cpp')
2.61 + else:
2.62 + files.append('smn_bitbuffer.cpp')
2.63 +
2.64 binary.AddSourceFiles('core', files)
2.65 +
2.66 + if i == 'csgo':
2.67 + files = [
2.68 + os.path.join('public', 'engine', 'protobuf', 'netmessages.pb.cc'),
2.69 + os.path.join('public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessages.pb.cc'),
2.70 + os.path.join('public', 'game', 'shared', 'csgo', 'protobuf', 'cstrike15_usermessage_helpers.cpp'),
2.71 + ]
2.72 + binary.AddSourceFiles(AMBuild.cache[sdk['sdk']], files)
2.73 +
2.74 SM.PostSetupHL2Job(extension, binary, i)
2.75 SM.AutoVersion('core', binary)
2.76 binary.SendToJob()
3.1 --- a/core/HalfLife2.cpp Mon Jan 07 09:09:14 2013 -0500
3.2 +++ b/core/HalfLife2.cpp Tue Jan 22 21:43:12 2013 -0500
3.3 @@ -42,6 +42,10 @@
3.4 #include "logic_bridge.h"
3.5 #include <tier0/mem.h>
3.6
3.7 +#if SOURCE_ENGINE == SE_CSGO
3.8 +#include <cstrike15_usermessages.pb.h>
3.9 +#endif
3.10 +
3.11
3.12 typedef ICommandLine *(*FakeGetCommandLine)();
3.13
3.14 @@ -487,7 +491,9 @@
3.15
3.16 bool CHalfLife2::TextMsg(int client, int dest, const char *msg)
3.17 {
3.18 +#if SOURCE_ENGINE != SE_CSGO
3.19 bf_write *pBitBuf = NULL;
3.20 +#endif
3.21 cell_t players[] = {client};
3.22
3.23 if (dest == HUD_PRINTTALK)
3.24 @@ -500,7 +506,18 @@
3.25 char buffer[192];
3.26 UTIL_Format(buffer, sizeof(buffer), "%s\1\n", msg);
3.27
3.28 - if ((pBitBuf = g_UserMsgs.StartMessage(m_SayTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
3.29 +#if SOURCE_ENGINE == SE_CSGO
3.30 + CCSUsrMsg_SayText *pMsg;
3.31 + if ((pMsg = (CCSUsrMsg_SayText *)g_UserMsgs.StartProtobufMessage(m_SayTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
3.32 + {
3.33 + return false;
3.34 + }
3.35 +
3.36 + pMsg->set_ent_idx(0);
3.37 + pMsg->set_text(buffer);
3.38 + pMsg->set_chat(false);
3.39 +#else
3.40 + if ((pBitBuf = g_UserMsgs.StartBitBufMessage(m_SayTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
3.41 {
3.42 return false;
3.43 }
3.44 @@ -508,6 +525,7 @@
3.45 pBitBuf->WriteByte(0);
3.46 pBitBuf->WriteString(buffer);
3.47 pBitBuf->WriteByte(1);
3.48 +#endif
3.49
3.50 g_UserMsgs.EndMessage();
3.51
3.52 @@ -515,13 +533,29 @@
3.53 }
3.54 }
3.55
3.56 - if ((pBitBuf = g_UserMsgs.StartMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
3.57 +#if SOURCE_ENGINE == SE_CSGO
3.58 + CCSUsrMsg_TextMsg *pMsg;
3.59 + if ((pMsg = (CCSUsrMsg_TextMsg *)g_UserMsgs.StartProtobufMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
3.60 + {
3.61 + return false;
3.62 + }
3.63 +
3.64 + // Client tries to read all 5 'params' and will crash if less
3.65 + pMsg->set_msg_dst(dest);
3.66 + pMsg->add_params(msg);
3.67 + pMsg->add_params("");
3.68 + pMsg->add_params("");
3.69 + pMsg->add_params("");
3.70 + pMsg->add_params("");
3.71 +#else
3.72 + if ((pBitBuf = g_UserMsgs.StartBitBufMessage(m_MsgTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
3.73 {
3.74 return false;
3.75 }
3.76
3.77 pBitBuf->WriteByte(dest);
3.78 pBitBuf->WriteString(msg);
3.79 +#endif
3.80
3.81 g_UserMsgs.EndMessage();
3.82
3.83 @@ -530,10 +564,20 @@
3.84
3.85 bool CHalfLife2::HintTextMsg(int client, const char *msg)
3.86 {
3.87 - bf_write *pBitBuf = NULL;
3.88 cell_t players[] = {client};
3.89
3.90 - if ((pBitBuf = g_UserMsgs.StartMessage(m_HinTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
3.91 +#if SOURCE_ENGINE == SE_CSGO
3.92 + CCSUsrMsg_HintText *pMsg;
3.93 + if ((pMsg = (CCSUsrMsg_HintText *)g_UserMsgs.StartProtobufMessage(m_HinTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
3.94 + {
3.95 + return false;
3.96 + }
3.97 +
3.98 + pMsg->set_text(msg);
3.99 +#else
3.100 + bf_write *pBitBuf = NULL;
3.101 +
3.102 + if ((pBitBuf = g_UserMsgs.StartBitBufMessage(m_HinTextMsg, players, 1, USERMSG_RELIABLE)) == NULL)
3.103 {
3.104 return false;
3.105 }
3.106 @@ -544,6 +588,7 @@
3.107 pBitBuf->WriteByte(1);
3.108 }
3.109 pBitBuf->WriteString(msg);
3.110 +#endif
3.111 g_UserMsgs.EndMessage();
3.112
3.113 return true;
3.114 @@ -551,9 +596,18 @@
3.115
3.116 bool CHalfLife2::HintTextMsg(cell_t *players, int count, const char *msg)
3.117 {
3.118 +#if SOURCE_ENGINE == SE_CSGO
3.119 + CCSUsrMsg_HintText *pMsg;
3.120 + if ((pMsg = (CCSUsrMsg_HintText *)g_UserMsgs.StartProtobufMessage(m_HinTextMsg, players, count, USERMSG_RELIABLE)) == NULL)
3.121 + {
3.122 + return false;
3.123 + }
3.124 +
3.125 + pMsg->set_text(msg);
3.126 +#else
3.127 bf_write *pBitBuf = NULL;
3.128
3.129 - if ((pBitBuf = g_UserMsgs.StartMessage(m_HinTextMsg, players, count, USERMSG_RELIABLE)) == NULL)
3.130 + if ((pBitBuf = g_UserMsgs.StartBitBufMessage(m_HinTextMsg, players, count, USERMSG_RELIABLE)) == NULL)
3.131 {
3.132 return false;
3.133 }
3.134 @@ -564,6 +618,8 @@
3.135 pBitBuf->WriteByte(1);
3.136 }
3.137 pBitBuf->WriteString(msg);
3.138 +#endif
3.139 +
3.140 g_UserMsgs.EndMessage();
3.141
3.142 return true;
3.143 @@ -571,15 +627,23 @@
3.144
3.145 bool CHalfLife2::ShowVGUIMenu(int client, const char *name, KeyValues *data, bool show)
3.146 {
3.147 - bf_write *pBitBuf = NULL;
3.148 KeyValues *SubKey = NULL;
3.149 int count = 0;
3.150 cell_t players[] = {client};
3.151
3.152 - if ((pBitBuf = g_UserMsgs.StartMessage(m_VGUIMenu, players, 1, USERMSG_RELIABLE)) == NULL)
3.153 +#if SOURCE_ENGINE == SE_CSGO
3.154 + CCSUsrMsg_VGUIMenu *pMsg;
3.155 + if ((pMsg = (CCSUsrMsg_VGUIMenu *)g_UserMsgs.StartProtobufMessage(m_VGUIMenu, players, 1, USERMSG_RELIABLE)) == NULL)
3.156 {
3.157 return false;
3.158 }
3.159 +#else
3.160 + bf_write *pBitBuf = NULL;
3.161 + if ((pBitBuf = g_UserMsgs.StartBitBufMessage(m_VGUIMenu, players, 1, USERMSG_RELIABLE)) == NULL)
3.162 + {
3.163 + return false;
3.164 + }
3.165 +#endif
3.166
3.167 if (data)
3.168 {
3.169 @@ -592,6 +656,18 @@
3.170 SubKey = data->GetFirstSubKey();
3.171 }
3.172
3.173 +#if SOURCE_ENGINE == SE_CSGO
3.174 + pMsg->set_name(name);
3.175 + pMsg->set_show(show);
3.176 +
3.177 + while (SubKey)
3.178 + {
3.179 + CCSUsrMsg_VGUIMenu_Subkey *key = pMsg->add_subkeys();
3.180 + key->set_name(SubKey->GetName());
3.181 + key->set_str(SubKey->GetString());
3.182 + SubKey = SubKey->GetNextKey();
3.183 + }
3.184 +#else
3.185 pBitBuf->WriteString(name);
3.186 pBitBuf->WriteByte((show) ? 1 : 0);
3.187 pBitBuf->WriteByte(count);
3.188 @@ -601,6 +677,8 @@
3.189 pBitBuf->WriteString(SubKey->GetString());
3.190 SubKey = SubKey->GetNextKey();
3.191 }
3.192 +#endif
3.193 +
3.194 g_UserMsgs.EndMessage();
3.195
3.196 return true;
4.1 --- a/core/MenuStyle_Radio.cpp Mon Jan 07 09:09:14 2013 -0500
4.2 +++ b/core/MenuStyle_Radio.cpp Tue Jan 22 21:43:12 2013 -0500
4.3 @@ -39,6 +39,14 @@
4.4 #endif
4.5 #include "logic_bridge.h"
4.6
4.7 +#ifdef USE_PROTOBUF_USERMESSAGES
4.8 +#include <google/protobuf/descriptor.h>
4.9 +#endif
4.10 +
4.11 +#if SOURCE_ENGINE == SE_CSGO
4.12 +#include <game/shared/csgo/protobuf/cstrike15_usermessages.pb.h>
4.13 +#endif
4.14 +
4.15 extern const char *g_RadioNumTable[];
4.16 CRadioStyle g_RadioMenuStyle;
4.17 int g_ShowMenuId = -1;
4.18 @@ -155,13 +163,22 @@
4.19 static unsigned int g_last_client_count = 0;
4.20 static int g_last_clients[256];
4.21
4.22 +#ifdef USE_PROTOBUF_USERMESSAGES
4.23 +void CRadioStyle::OnUserMessage(int msg_id, protobuf::Message &msg, IRecipientFilter *pFilter)
4.24 +#else
4.25 void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
4.26 +#endif
4.27 {
4.28 int count = pFilter->GetRecipientCount();
4.29 +
4.30 +#ifdef USE_PROTOBUF_USERMESSAGES
4.31 + int c = ((CCSUsrMsg_ShowMenu &)msg).display_time();
4.32 +#else
4.33 bf_read br(bf->GetBasePointer(), 3);
4.34
4.35 br.ReadWord();
4.36 int c = br.ReadChar();
4.37 +#endif
4.38
4.39 g_last_holdtime = (c == -1) ? 0 : (unsigned)c;
4.40
4.41 @@ -472,6 +489,15 @@
4.42 time = menuHoldTime - (unsigned int)(gpGlobals->curtime - menuStartTime);
4.43 }
4.44
4.45 +#ifdef USE_PROTOBUF_USERMESSAGES
4.46 + // If or when we need to support multiple games per engine with this, we can switch to reflection
4.47 + // TODO: find what happens past 240 on CS:GO
4.48 + CCSUsrMsg_ShowMenu *msg = (CCSUsrMsg_ShowMenu *)g_UserMsgs.StartProtobufMessage(g_ShowMenuId, players, 1, USERMSG_BLOCKHOOKS);
4.49 + msg->set_bits_valid_slots(display_keys);
4.50 + msg->set_display_time(time);
4.51 + msg->set_menu_string(ptr);
4.52 + g_UserMsgs.EndMessage();
4.53 +#else
4.54 while (true)
4.55 {
4.56 if (len > 240)
4.57 @@ -479,7 +505,8 @@
4.58 save = ptr[240];
4.59 ptr[240] = '\0';
4.60 }
4.61 - bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, USERMSG_BLOCKHOOKS);
4.62 +
4.63 + bf_write *buffer = g_UserMsgs.StartBitBufMessage(g_ShowMenuId, players, 1, USERMSG_BLOCKHOOKS);
4.64 buffer->WriteWord(display_keys);
4.65 buffer->WriteChar(time ? time : -1);
4.66 buffer->WriteByte( (len > 240) ? 1 : 0 );
4.67 @@ -496,6 +523,7 @@
4.68 break;
4.69 }
4.70 }
4.71 +#endif
4.72
4.73 display_last_refresh = gpGlobals->curtime;
4.74 }
5.1 --- a/core/MenuStyle_Radio.h Mon Jan 07 09:09:14 2013 -0500
5.2 +++ b/core/MenuStyle_Radio.h Tue Jan 22 21:43:12 2013 -0500
5.3 @@ -37,7 +37,7 @@
5.4 #include "MenuStyle_Base.h"
5.5 #include "sourcemm_api.h"
5.6 #include <IPlayerHelpers.h>
5.7 -#include <IUserMessages.h>
5.8 +#include "UserMessages.h"
5.9 #include "sm_fastlink.h"
5.10 #include <sh_stack.h>
5.11 #include <compat_wrappers.h>
5.12 @@ -65,7 +65,11 @@
5.13 class CRadioStyle :
5.14 public BaseMenuStyle,
5.15 public SMGlobalClass,
5.16 - public IUserMessageListener
5.17 +#ifdef USE_PROTOBUF_USERMESSAGES
5.18 + public IProtobufUserMessageListener
5.19 +#else
5.20 + public IBitBufUserMessageListener
5.21 +#endif
5.22 {
5.23 public:
5.24 CRadioStyle();
5.25 @@ -84,7 +88,11 @@
5.26 unsigned int GetMaxPageItems();
5.27 unsigned int GetApproxMemUsage();
5.28 public: //IUserMessageListener
5.29 +#ifdef USE_PROTOBUF_USERMESSAGES
5.30 + void OnUserMessage(int msg_id, protobuf::Message &msg, IRecipientFilter *pFilter);
5.31 +#else
5.32 void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
5.33 +#endif
5.34 void OnUserMessageSent(int msg_id);
5.35 public:
5.36 bool IsSupported();
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/core/UserMessagePBHelpers.h Tue Jan 22 21:43:12 2013 -0500
6.3 @@ -0,0 +1,853 @@
6.4 +/**
6.5 + * vim: set ts=4 :
6.6 + * =============================================================================
6.7 + * SourceMod
6.8 + * Copyright (C) 2013 AlliedModders LLC. All rights reserved.
6.9 + * =============================================================================
6.10 + *
6.11 + * This program is free software; you can redistribute it and/or modify it under
6.12 + * the terms of the GNU General Public License, version 3.0, as published by the
6.13 + * Free Software Foundation.
6.14 + *
6.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
6.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
6.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
6.18 + * details.
6.19 + *
6.20 + * You should have received a copy of the GNU General Public License along with
6.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
6.22 + *
6.23 + * As a special exception, AlliedModders LLC gives you permission to link the
6.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
6.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
6.26 + * by the Valve Corporation. You must obey the GNU General Public License in
6.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
6.28 + * this exception to all derivative works. AlliedModders LLC defines further
6.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
6.30 + * or <http://www.sourcemod.net/license.php>.
6.31 + *
6.32 + * Version: $Id$
6.33 + */
6.34 +
6.35 +#ifndef _INCLUDE_SOURCEMOD_SMPBMESSAGE_H_
6.36 +#define _INCLUDE_SOURCEMOD_SMPBMESSAGE_H_
6.37 +
6.38 +#include <sh_list.h>
6.39 +#include <google/protobuf/descriptor.h>
6.40 +
6.41 +#define GETCHECK_FIELD() \
6.42 + const protobuf::FieldDescriptor *field = msg->GetDescriptor()->FindFieldByName(pszFieldName); \
6.43 + if (!field) \
6.44 + { \
6.45 + return false; \
6.46 + }
6.47 +
6.48 +#define CHECK_FIELD_TYPE(type) \
6.49 + if (field->cpp_type() != protobuf::FieldDescriptor::CPPTYPE_##type) \
6.50 + { \
6.51 + return false; \
6.52 + }
6.53 +
6.54 +#define CHECK_FIELD_TYPE2(type1, type2) \
6.55 + protobuf::FieldDescriptor::CppType fieldType = field->cpp_type(); \
6.56 + if (fieldType != protobuf::FieldDescriptor::CPPTYPE_##type1 \
6.57 + && fieldType != protobuf::FieldDescriptor::CPPTYPE_##type2) \
6.58 + { \
6.59 + return false; \
6.60 + }
6.61 +
6.62 +#define CHECK_FIELD_REPEATED() \
6.63 + if (field->label() != protobuf::FieldDescriptor::LABEL_REPEATED) \
6.64 + { \
6.65 + return false; \
6.66 + }
6.67 +
6.68 +#define CHECK_FIELD_NOT_REPEATED() \
6.69 + if (field->label() == protobuf::FieldDescriptor::LABEL_REPEATED) \
6.70 + { \
6.71 + return false; \
6.72 + }
6.73 +
6.74 +#define CHECK_REPEATED_ELEMENT(idx) \
6.75 + int elemCount = msg->GetReflection()->FieldSize(*msg, field); \
6.76 + if (elemCount == 0 || idx >= elemCount || idx <= 0) \
6.77 + { \
6.78 + return false; \
6.79 + }
6.80 +
6.81 +typedef List<Handle_t> PBHandleList;
6.82 +
6.83 +class SMProtobufMessage
6.84 +{
6.85 +public:
6.86 + SMProtobufMessage( protobuf::Message *message )
6.87 + {
6.88 + msg = message;
6.89 + }
6.90 +
6.91 + ~SMProtobufMessage()
6.92 + {
6.93 + PBHandleList::iterator iter = childHandles.begin();
6.94 + while (iter != childHandles.end())
6.95 + {
6.96 + Handle_t &hndl = (*iter);
6.97 + HandleSecurity sec;
6.98 + sec.pIdentity = g_pCoreIdent;
6.99 + g_HandleSys.FreeHandle(hndl, &sec);
6.100 + iter = childHandles.erase(iter);
6.101 + }
6.102 + }
6.103 +
6.104 + inline void AddChildHandle(Handle_t hndl)
6.105 + {
6.106 + childHandles.push_back(hndl);
6.107 + }
6.108 +
6.109 + inline protobuf::Message *GetProtobufMessage()
6.110 + {
6.111 + return msg;
6.112 + }
6.113 +
6.114 + inline bool GetInt32(const char *pszFieldName, int32 *out)
6.115 + {
6.116 + GETCHECK_FIELD();
6.117 + CHECK_FIELD_TYPE(INT32);
6.118 + CHECK_FIELD_NOT_REPEATED();
6.119 +
6.120 + *out = msg->GetReflection()->GetInt32(*msg, field);
6.121 + return true;
6.122 + }
6.123 +
6.124 + inline bool SetInt32(const char *pszFieldName, int32 value)
6.125 + {
6.126 + GETCHECK_FIELD();
6.127 + CHECK_FIELD_TYPE(INT32);
6.128 + CHECK_FIELD_NOT_REPEATED();
6.129 +
6.130 + msg->GetReflection()->SetInt32(msg, field, value);
6.131 + return true;
6.132 + }
6.133 +
6.134 + inline bool GetRepeatedInt32(const char *pszFieldName, int index, int32 *out)
6.135 + {
6.136 + GETCHECK_FIELD();
6.137 + CHECK_FIELD_TYPE(INT32);
6.138 + CHECK_FIELD_REPEATED();
6.139 + CHECK_REPEATED_ELEMENT(index);
6.140 +
6.141 + *out = msg->GetReflection()->GetRepeatedInt32(*msg, field, index);
6.142 + return true;
6.143 + }
6.144 +
6.145 + inline bool AddInt32(const char *pszFieldName, int32 value)
6.146 + {
6.147 + GETCHECK_FIELD();
6.148 + CHECK_FIELD_TYPE(INT32);
6.149 + CHECK_FIELD_REPEATED();
6.150 +
6.151 + msg->GetReflection()->AddInt32(msg, field, value);
6.152 + return true;
6.153 + }
6.154 +
6.155 + inline bool GetInt64(const char *pszFieldName, int64 *out)
6.156 + {
6.157 + GETCHECK_FIELD();
6.158 + CHECK_FIELD_TYPE(INT64);
6.159 + CHECK_FIELD_NOT_REPEATED();
6.160 +
6.161 + *out = msg->GetReflection()->GetInt64(*msg, field);
6.162 + return true;
6.163 + }
6.164 +
6.165 + inline bool SetInt64(const char *pszFieldName, int64 value)
6.166 + {
6.167 + GETCHECK_FIELD();
6.168 + CHECK_FIELD_TYPE(INT64);
6.169 + CHECK_FIELD_NOT_REPEATED();
6.170 +
6.171 + msg->GetReflection()->SetInt64(msg, field, value);
6.172 + return true;
6.173 + }
6.174 +
6.175 + inline bool GetRepeatedInt64(const char *pszFieldName, int index, int64 *out)
6.176 + {
6.177 + GETCHECK_FIELD();
6.178 + CHECK_FIELD_TYPE(INT64);
6.179 + CHECK_FIELD_REPEATED();
6.180 + CHECK_REPEATED_ELEMENT(index);
6.181 +
6.182 + *out = msg->GetReflection()->GetRepeatedInt64(*msg, field, index);
6.183 + return true;
6.184 + }
6.185 +
6.186 + inline bool AddInt64(const char *pszFieldName, int64 value)
6.187 + {
6.188 + GETCHECK_FIELD();
6.189 + CHECK_FIELD_TYPE(INT64);
6.190 + CHECK_FIELD_REPEATED();
6.191 +
6.192 + msg->GetReflection()->AddInt64(msg, field, value);
6.193 + return true;
6.194 + }
6.195 +
6.196 + inline bool GetUInt32(const char *pszFieldName, uint32 *out)
6.197 + {
6.198 + GETCHECK_FIELD();
6.199 + CHECK_FIELD_TYPE(UINT32);
6.200 + CHECK_FIELD_NOT_REPEATED();
6.201 +
6.202 + *out = msg->GetReflection()->GetUInt32(*msg, field);
6.203 + return true;
6.204 + }
6.205 +
6.206 + inline bool SetUInt32(const char *pszFieldName, uint32 value)
6.207 + {
6.208 + GETCHECK_FIELD();
6.209 + CHECK_FIELD_TYPE(UINT32);
6.210 + CHECK_FIELD_NOT_REPEATED();
6.211 +
6.212 + msg->GetReflection()->SetUInt32(msg, field, value);
6.213 + return true;
6.214 + }
6.215 +
6.216 + inline bool GetRepeatedUInt32(const char *pszFieldName, int index, uint32 *out)
6.217 + {
6.218 + GETCHECK_FIELD();
6.219 + CHECK_FIELD_TYPE(UINT32);
6.220 + CHECK_FIELD_REPEATED();
6.221 + CHECK_REPEATED_ELEMENT(index);
6.222 +
6.223 + *out = msg->GetReflection()->GetRepeatedUInt32(*msg, field, index);
6.224 + return true;
6.225 + }
6.226 +
6.227 + inline bool AddUInt32(const char *pszFieldName, uint32 value)
6.228 + {
6.229 + GETCHECK_FIELD();
6.230 + CHECK_FIELD_TYPE(UINT32);
6.231 + CHECK_FIELD_REPEATED();
6.232 +
6.233 + msg->GetReflection()->AddUInt32(msg, field, value);
6.234 + return true;
6.235 + }
6.236 +
6.237 + inline bool GetUInt64(const char *pszFieldName, uint64 *out)
6.238 + {
6.239 + GETCHECK_FIELD();
6.240 + CHECK_FIELD_TYPE(UINT64);
6.241 + CHECK_FIELD_NOT_REPEATED();
6.242 +
6.243 + *out = msg->GetReflection()->GetUInt64(*msg, field);
6.244 + return true;
6.245 + }
6.246 +
6.247 + inline bool SetUInt64(const char *pszFieldName, uint64 value)
6.248 + {
6.249 + GETCHECK_FIELD();
6.250 + CHECK_FIELD_TYPE(UINT64);
6.251 + CHECK_FIELD_NOT_REPEATED();
6.252 +
6.253 + msg->GetReflection()->SetUInt64(msg, field, value);
6.254 + return true;
6.255 + }
6.256 +
6.257 + inline bool GetRepeatedUInt64(const char *pszFieldName, int index, uint64 *out)
6.258 + {
6.259 + GETCHECK_FIELD();
6.260 + CHECK_FIELD_TYPE(UINT64);
6.261 + CHECK_FIELD_REPEATED();
6.262 + CHECK_REPEATED_ELEMENT(index);
6.263 +
6.264 + *out = msg->GetReflection()->GetRepeatedUInt64(*msg, field, index);
6.265 + return true;
6.266 + }
6.267 +
6.268 + inline bool AddUInt64(const char *pszFieldName, uint64 value)
6.269 + {
6.270 + GETCHECK_FIELD();
6.271 + CHECK_FIELD_TYPE(UINT64);
6.272 + CHECK_FIELD_REPEATED();
6.273 +
6.274 + msg->GetReflection()->AddUInt32(msg, field, value);
6.275 + return true;
6.276 + }
6.277 +
6.278 + inline bool GetInt32OrUnsigned(const char *pszFieldName, int32 *out)
6.279 + {
6.280 + GETCHECK_FIELD();
6.281 + CHECK_FIELD_TYPE2(INT32, UINT32);
6.282 + CHECK_FIELD_NOT_REPEATED();
6.283 +
6.284 + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
6.285 + *out = (int32)msg->GetReflection()->GetUInt32(*msg, field);
6.286 + else
6.287 + *out = msg->GetReflection()->GetInt32(*msg, field);
6.288 +
6.289 + return true;
6.290 + }
6.291 +
6.292 + inline bool SetInt32OrUnsigned(const char *pszFieldName, int32 value)
6.293 + {
6.294 + GETCHECK_FIELD();
6.295 + CHECK_FIELD_TYPE2(INT32, UINT32);
6.296 + CHECK_FIELD_NOT_REPEATED();
6.297 +
6.298 + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
6.299 + msg->GetReflection()->SetUInt32(msg, field, (uint32)value);
6.300 + else
6.301 + msg->GetReflection()->SetInt32(msg, field, value);
6.302 +
6.303 + return true;
6.304 + }
6.305 +
6.306 + inline bool GetRepeatedInt32OrUnsigned(const char *pszFieldName, int index, int32 *out)
6.307 + {
6.308 + GETCHECK_FIELD();
6.309 + CHECK_FIELD_TYPE2(INT32, UINT32);
6.310 + CHECK_FIELD_REPEATED();
6.311 + CHECK_REPEATED_ELEMENT(index);
6.312 +
6.313 + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
6.314 + *out = (int32)msg->GetReflection()->GetRepeatedUInt32(*msg, field, index);
6.315 + else
6.316 + *out = msg->GetReflection()->GetRepeatedInt32(*msg, field, index);
6.317 +
6.318 + return true;
6.319 + }
6.320 +
6.321 + inline bool AddInt32OrUnsigned(const char *pszFieldName, int32 value)
6.322 + {
6.323 + GETCHECK_FIELD();
6.324 + CHECK_FIELD_TYPE2(INT32, UINT32);
6.325 + CHECK_FIELD_REPEATED();
6.326 +
6.327 + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_UINT32)
6.328 + msg->GetReflection()->AddUInt32(msg, field, (uint32)value);
6.329 + else
6.330 + msg->GetReflection()->AddInt32(msg, field, value);
6.331 +
6.332 + return true;
6.333 + }
6.334 +
6.335 + inline bool GetBool(const char *pszFieldName, bool *out)
6.336 + {
6.337 + GETCHECK_FIELD();
6.338 + CHECK_FIELD_TYPE(BOOL);
6.339 + CHECK_FIELD_NOT_REPEATED();
6.340 +
6.341 + *out = msg->GetReflection()->GetBool(*msg, field);
6.342 + return true;
6.343 + }
6.344 +
6.345 + inline bool SetBool(const char *pszFieldName, bool value)
6.346 + {
6.347 + GETCHECK_FIELD();
6.348 + CHECK_FIELD_TYPE(BOOL);
6.349 + CHECK_FIELD_NOT_REPEATED();
6.350 +
6.351 + msg->GetReflection()->SetBool(msg, field, value);
6.352 + return true;
6.353 + }
6.354 +
6.355 + inline bool GetRepeatedBool(const char *pszFieldName, int index, bool *out)
6.356 + {
6.357 + GETCHECK_FIELD();
6.358 + CHECK_FIELD_TYPE(BOOL);
6.359 + CHECK_FIELD_REPEATED();
6.360 + CHECK_REPEATED_ELEMENT(index);
6.361 +
6.362 + *out = msg->GetReflection()->GetRepeatedBool(*msg, field, index);
6.363 + return true;
6.364 + }
6.365 +
6.366 + inline bool AddBool(const char *pszFieldName, bool value)
6.367 + {
6.368 + GETCHECK_FIELD();
6.369 + CHECK_FIELD_TYPE(BOOL);
6.370 + CHECK_FIELD_REPEATED();
6.371 +
6.372 + msg->GetReflection()->AddBool(msg, field, value);
6.373 + return true;
6.374 + }
6.375 +
6.376 + inline bool GetFloat(const char *pszFieldName, float *out)
6.377 + {
6.378 + GETCHECK_FIELD();
6.379 + CHECK_FIELD_TYPE(FLOAT);
6.380 + CHECK_FIELD_NOT_REPEATED();
6.381 +
6.382 + *out = msg->GetReflection()->GetFloat(*msg, field);
6.383 + return true;
6.384 + }
6.385 +
6.386 + inline bool SetFloat(const char *pszFieldName, float value)
6.387 + {
6.388 + GETCHECK_FIELD();
6.389 + CHECK_FIELD_TYPE(FLOAT);
6.390 + CHECK_FIELD_NOT_REPEATED();
6.391 +
6.392 + msg->GetReflection()->SetFloat(msg, field, value);
6.393 + return true;
6.394 + }
6.395 +
6.396 + inline bool GetRepeatedFloat(const char *pszFieldName, int index, float *out)
6.397 + {
6.398 + GETCHECK_FIELD();
6.399 + CHECK_FIELD_TYPE(FLOAT);
6.400 + CHECK_FIELD_REPEATED();
6.401 + CHECK_REPEATED_ELEMENT(index);
6.402 +
6.403 + *out = msg->GetReflection()->GetRepeatedFloat(*msg, field, index);
6.404 + return true;
6.405 + }
6.406 +
6.407 + inline bool AddFloat(const char *pszFieldName, float value)
6.408 + {
6.409 + GETCHECK_FIELD();
6.410 + CHECK_FIELD_TYPE(FLOAT);
6.411 + CHECK_FIELD_REPEATED();
6.412 +
6.413 + msg->GetReflection()->AddFloat(msg, field, value);
6.414 + return true;
6.415 + }
6.416 +
6.417 + inline bool GetDouble(const char *pszFieldName, double *out)
6.418 + {
6.419 + GETCHECK_FIELD();
6.420 + CHECK_FIELD_TYPE(DOUBLE);
6.421 + CHECK_FIELD_NOT_REPEATED();
6.422 +
6.423 + *out = msg->GetReflection()->GetDouble(*msg, field);
6.424 + return true;
6.425 + }
6.426 +
6.427 + inline bool SetDouble(const char *pszFieldName, double value)
6.428 + {
6.429 + GETCHECK_FIELD();
6.430 + CHECK_FIELD_TYPE(DOUBLE);
6.431 + CHECK_FIELD_NOT_REPEATED();
6.432 +
6.433 + msg->GetReflection()->SetDouble(msg, field, value);
6.434 + return true;
6.435 + }
6.436 +
6.437 + inline bool GetRepeatedDouble(const char *pszFieldName, int index, double *out)
6.438 + {
6.439 + GETCHECK_FIELD();
6.440 + CHECK_FIELD_TYPE(DOUBLE);
6.441 + CHECK_FIELD_REPEATED();
6.442 + CHECK_REPEATED_ELEMENT(index);
6.443 +
6.444 + *out = msg->GetReflection()->GetRepeatedDouble(*msg, field, index);
6.445 + return true;
6.446 + }
6.447 +
6.448 + inline bool AddDouble(const char *pszFieldName, double value)
6.449 + {
6.450 + GETCHECK_FIELD();
6.451 + CHECK_FIELD_TYPE(DOUBLE);
6.452 + CHECK_FIELD_REPEATED();
6.453 +
6.454 + msg->GetReflection()->AddDouble(msg, field, value);
6.455 + return true;
6.456 + }
6.457 +
6.458 + inline bool GetFloatOrDouble(const char *pszFieldName, float *out)
6.459 + {
6.460 + GETCHECK_FIELD();
6.461 + CHECK_FIELD_TYPE2(FLOAT, DOUBLE);
6.462 + CHECK_FIELD_NOT_REPEATED();
6.463 +
6.464 + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_DOUBLE)
6.465 + *out = (float)msg->GetReflection()->GetDouble(*msg, field);
6.466 + else
6.467 + *out = msg->GetReflection()->GetFloat(*msg, field);
6.468 +
6.469 + return true;
6.470 + }
6.471 +
6.472 + inline bool SetFloatOrDouble(const char *pszFieldName, float value)
6.473 + {
6.474 + GETCHECK_FIELD();
6.475 + CHECK_FIELD_TYPE2(FLOAT, DOUBLE);
6.476 + CHECK_FIELD_NOT_REPEATED();
6.477 +
6.478 + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_DOUBLE)
6.479 + msg->GetReflection()->SetDouble(msg, field, (double)value);
6.480 + else
6.481 + msg->GetReflection()->SetFloat(msg, field, value);
6.482 +
6.483 + return true;
6.484 + }
6.485 +
6.486 + inline bool GetRepeatedFloatOrDouble(const char *pszFieldName, int index, float *out)
6.487 + {
6.488 + GETCHECK_FIELD();
6.489 + CHECK_FIELD_TYPE2(FLOAT, DOUBLE);
6.490 + CHECK_FIELD_REPEATED();
6.491 + CHECK_REPEATED_ELEMENT(index);
6.492 +
6.493 + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_DOUBLE)
6.494 + *out = (float)msg->GetReflection()->GetRepeatedDouble(*msg, field, index);
6.495 + else
6.496 + *out = msg->GetReflection()->GetRepeatedFloat(*msg, field, index);
6.497 +
6.498 + return true;
6.499 + }
6.500 +
6.501 + inline bool AddFloatOrDouble(const char *pszFieldName, float value)
6.502 + {
6.503 + GETCHECK_FIELD();
6.504 + CHECK_FIELD_TYPE2(FLOAT, DOUBLE);
6.505 + CHECK_FIELD_REPEATED();
6.506 +
6.507 + if (fieldType == protobuf::FieldDescriptor::CPPTYPE_DOUBLE)
6.508 + msg->GetReflection()->AddDouble(msg, field, (double)value);
6.509 + else
6.510 + msg->GetReflection()->AddFloat(msg, field, value);
6.511 +
6.512 + return true;
6.513 + }
6.514 +
6.515 + inline bool GetString(const char *pszFieldName, char *out, int size)
6.516 + {
6.517 + GETCHECK_FIELD();
6.518 + CHECK_FIELD_TYPE(STRING);
6.519 + CHECK_FIELD_NOT_REPEATED();
6.520 +
6.521 + std::string scratch;
6.522 + strncopy(out, msg->GetReflection()->GetStringReference(*msg, field, &buffer).c_str(), size);
6.523 +
6.524 + return true;
6.525 + }
6.526 +
6.527 + inline bool SetString(const char *pszFieldName, const char *value)
6.528 + {
6.529 + GETCHECK_FIELD();
6.530 + CHECK_FIELD_TYPE(STRING);
6.531 + CHECK_FIELD_NOT_REPEATED();
6.532 +
6.533 + msg->GetReflection()->SetString(msg, field, value);
6.534 + return true;
6.535 + }
6.536 +
6.537 + inline bool GetRepeatedString(const char *pszFieldName, int index, char *out, int size)
6.538 + {
6.539 + GETCHECK_FIELD();
6.540 + CHECK_FIELD_TYPE(STRING);
6.541 + CHECK_FIELD_REPEATED();
6.542 + CHECK_REPEATED_ELEMENT(index);
6.543 +
6.544 + std::string scratch;
6.545 + strncopy(out, msg->GetReflection()->GetRepeatedStringReference(*msg, field, index, &scratch).c_str(), size);
6.546 +
6.547 + return true;
6.548 + }
6.549 +
6.550 + inline bool AddString(const char *pszFieldName, const char *value)
6.551 + {
6.552 + GETCHECK_FIELD();
6.553 + CHECK_FIELD_TYPE(STRING);
6.554 + CHECK_FIELD_REPEATED();
6.555 +
6.556 + msg->GetReflection()->AddString(msg, field, value);
6.557 + return true;
6.558 + }
6.559 +
6.560 + inline bool GetColor(const char *pszFieldName, Color *out)
6.561 + {
6.562 + GETCHECK_FIELD();
6.563 + CHECK_FIELD_TYPE(MESSAGE);
6.564 + CHECK_FIELD_NOT_REPEATED();
6.565 +
6.566 + const CMsgRGBA &msgRGBA = (const CMsgRGBA &)msg->GetReflection()->GetMessage(*msg, field);
6.567 + out->SetColor(
6.568 + msgRGBA.r(),
6.569 + msgRGBA.g(),
6.570 + msgRGBA.b(),
6.571 + msgRGBA.a()
6.572 + );
6.573 +
6.574 + return true;
6.575 + }
6.576 +
6.577 + inline bool SetColor(const char *pszFieldName, const Color &value)
6.578 + {
6.579 + GETCHECK_FIELD();
6.580 + CHECK_FIELD_TYPE(MESSAGE);
6.581 + CHECK_FIELD_NOT_REPEATED();
6.582 +
6.583 + CMsgRGBA *msgRGBA = (CMsgRGBA *)msg->GetReflection()->MutableMessage(msg, field);
6.584 + msgRGBA->set_r(value.r());
6.585 + msgRGBA->set_g(value.g());
6.586 + msgRGBA->set_b(value.b());
6.587 + msgRGBA->set_a(value.a());
6.588 +
6.589 + return true;
6.590 + }
6.591 +
6.592 + inline bool GetRepeatedColor(const char *pszFieldName, int index, Color *out)
6.593 + {
6.594 + GETCHECK_FIELD();
6.595 + CHECK_FIELD_TYPE(MESSAGE);
6.596 + CHECK_FIELD_REPEATED();
6.597 + CHECK_REPEATED_ELEMENT(index);
6.598 +
6.599 + const CMsgRGBA &msgRGBA = (const CMsgRGBA &)msg->GetReflection()->GetRepeatedMessage(*msg, field, index);
6.600 + out->SetColor(
6.601 + msgRGBA.r(),
6.602 + msgRGBA.g(),
6.603 + msgRGBA.b(),
6.604 + msgRGBA.a()
6.605 + );
6.606 +
6.607 + return true;
6.608 + }
6.609 +
6.610 + inline bool AddColor(const char *pszFieldName, const Color &value)
6.611 + {
6.612 + GETCHECK_FIELD();
6.613 + CHECK_FIELD_TYPE(MESSAGE);
6.614 + CHECK_FIELD_REPEATED();
6.615 +
6.616 + CMsgRGBA *msgRGBA = (CMsgRGBA *)msg->GetReflection()->AddMessage(msg, field);
6.617 + msgRGBA->set_r(value.r());
6.618 + msgRGBA->set_g(value.g());
6.619 + msgRGBA->set_b(value.b());
6.620 + msgRGBA->set_a(value.a());
6.621 +
6.622 + return true;
6.623 + }
6.624 +
6.625 + inline bool GetVector2D(const char *pszFieldName, Vector2D *out)
6.626 + {
6.627 + GETCHECK_FIELD();
6.628 + CHECK_FIELD_TYPE(MESSAGE);
6.629 + CHECK_FIELD_NOT_REPEATED();
6.630 +
6.631 + const CMsgVector2D &msgVec2d = (const CMsgVector2D &)msg->GetReflection()->GetMessage(*msg, field);
6.632 + out->Init(
6.633 + msgVec2d.x(),
6.634 + msgVec2d.y()
6.635 + );
6.636 +
6.637 + return true;
6.638 + }
6.639 +
6.640 + inline bool SetVector2D(const char *pszFieldName, Vector2D &vec)
6.641 + {
6.642 + GETCHECK_FIELD();
6.643 + CHECK_FIELD_TYPE(MESSAGE);
6.644 + CHECK_FIELD_NOT_REPEATED();
6.645 +
6.646 + CMsgVector2D *msgVec2d = (CMsgVector2D *)msg->GetReflection()->MutableMessage(msg, field);
6.647 + msgVec2d->set_x(vec.x);
6.648 + msgVec2d->set_y(vec.y);
6.649 +
6.650 + return true;
6.651 + }
6.652 +
6.653 + inline bool GetRepeatedVector2D(const char *pszFieldName, int index, Vector2D *out)
6.654 + {
6.655 + GETCHECK_FIELD();
6.656 + CHECK_FIELD_TYPE(MESSAGE);
6.657 + CHECK_FIELD_REPEATED();
6.658 + CHECK_REPEATED_ELEMENT(index);
6.659 +
6.660 + const CMsgVector2D &msgVec2d = (const CMsgVector2D &)msg->GetReflection()->GetRepeatedMessage(*msg, field, index);
6.661 + out->Init(
6.662 + msgVec2d.x(),
6.663 + msgVec2d.y()
6.664 + );
6.665 +
6.666 + return true;
6.667 + }
6.668 +
6.669 + inline bool AddVector2D(const char *pszFieldName, Vector2D &vec)
6.670 + {
6.671 + GETCHECK_FIELD();
6.672 + CHECK_FIELD_TYPE(MESSAGE);
6.673 + CHECK_FIELD_REPEATED();
6.674 +
6.675 + CMsgVector2D *msgVec2d = (CMsgVector2D *)msg->GetReflection()->AddMessage(msg, field);
6.676 + msgVec2d->set_x(vec.x);
6.677 + msgVec2d->set_y(vec.y);
6.678 +
6.679 + return true;
6.680 + }
6.681 +
6.682 + inline bool GetVector(const char *pszFieldName, Vector *out)
6.683 + {
6.684 + GETCHECK_FIELD();
6.685 + CHECK_FIELD_TYPE(MESSAGE);
6.686 + CHECK_FIELD_NOT_REPEATED();
6.687 +
6.688 + const CMsgVector &msgVec = (const CMsgVector &)msg->GetReflection()->GetMessage(*msg, field);
6.689 + out->Init(
6.690 + msgVec.x(),
6.691 + msgVec.y(),
6.692 + msgVec.z()
6.693 + );
6.694 +
6.695 + return true;
6.696 + }
6.697 +
6.698 + inline bool SetVector(const char *pszFieldName, Vector &vec)
6.699 + {
6.700 + GETCHECK_FIELD();
6.701 + CHECK_FIELD_TYPE(MESSAGE);
6.702 + CHECK_FIELD_NOT_REPEATED();
6.703 +
6.704 + CMsgVector *msgVec = (CMsgVector *)msg->GetReflection()->MutableMessage(msg, field);
6.705 + msgVec->set_x(vec.x);
6.706 + msgVec->set_y(vec.y);
6.707 + msgVec->set_z(vec.z);
6.708 +
6.709 + return true;
6.710 + }
6.711 +
6.712 + inline bool GetRepeatedVector(const char *pszFieldName, int index, Vector *out)
6.713 + {
6.714 + GETCHECK_FIELD();
6.715 + CHECK_FIELD_TYPE(MESSAGE);
6.716 + CHECK_FIELD_REPEATED();
6.717 + CHECK_REPEATED_ELEMENT(index);
6.718 +
6.719 + const CMsgVector &msgVec = (const CMsgVector &)msg->GetReflection()->GetRepeatedMessage(*msg, field, index);
6.720 + out->Init(
6.721 + msgVec.x(),
6.722 + msgVec.y(),
6.723 + msgVec.z()
6.724 + );
6.725 +
6.726 + return true;
6.727 + }
6.728 +
6.729 + inline bool AddVector(const char *pszFieldName, Vector &vec)
6.730 + {
6.731 + GETCHECK_FIELD();
6.732 + CHECK_FIELD_TYPE(MESSAGE);
6.733 + CHECK_FIELD_REPEATED();
6.734 +
6.735 + CMsgVector *msgVec = (CMsgVector *)msg->GetReflection()->AddMessage(msg, field);
6.736 + msgVec->set_x(vec.x);
6.737 + msgVec->set_y(vec.y);
6.738 + msgVec->set_z(vec.z);
6.739 +
6.740 + return true;
6.741 + }
6.742 +
6.743 + inline bool GetQAngle(const char *pszFieldName, QAngle *out)
6.744 + {
6.745 + GETCHECK_FIELD();
6.746 + CHECK_FIELD_TYPE(MESSAGE);
6.747 + CHECK_FIELD_NOT_REPEATED();
6.748 +
6.749 + const CMsgQAngle &msgAng = (const CMsgQAngle &)msg->GetReflection()->GetMessage(*msg, field);
6.750 + out->Init(
6.751 + msgAng.x(),
6.752 + msgAng.y(),
6.753 + msgAng.z()
6.754 + );
6.755 +
6.756 + return true;
6.757 + }
6.758 +
6.759 + inline bool SetQAngle(const char *pszFieldName, QAngle &vec)
6.760 + {
6.761 + GETCHECK_FIELD();
6.762 + CHECK_FIELD_TYPE(MESSAGE);
6.763 + CHECK_FIELD_NOT_REPEATED();
6.764 +
6.765 + CMsgQAngle *msgAng = (CMsgQAngle *)msg->GetReflection()->MutableMessage(msg, field);
6.766 + msgAng->set_x(vec.x);
6.767 + msgAng->set_y(vec.y);
6.768 + msgAng->set_z(vec.z);
6.769 +
6.770 + return true;
6.771 + }
6.772 +
6.773 + inline bool GetRepeatedQAngle(const char *pszFieldName, int index, QAngle *out)
6.774 + {
6.775 + GETCHECK_FIELD();
6.776 + CHECK_FIELD_TYPE(MESSAGE);
6.777 + CHECK_FIELD_REPEATED();
6.778 + CHECK_REPEATED_ELEMENT(index);
6.779 +
6.780 + const CMsgQAngle &msgAng = (const CMsgQAngle &)msg->GetReflection()->GetRepeatedMessage(*msg, field, index);
6.781 + out->Init(
6.782 + msgAng.x(),
6.783 + msgAng.y(),
6.784 + msgAng.z()
6.785 + );
6.786 +
6.787 + return true;
6.788 + }
6.789 +
6.790 + inline bool AddQAngle(const char *pszFieldName, QAngle &vec)
6.791 + {
6.792 + GETCHECK_FIELD();
6.793 + CHECK_FIELD_TYPE(MESSAGE);
6.794 + CHECK_FIELD_REPEATED();
6.795 +
6.796 + CMsgQAngle *msgAng = (CMsgQAngle *)msg->GetReflection()->AddMessage(msg, field);
6.797 + msgAng->set_x(vec.x);
6.798 + msgAng->set_y(vec.y);
6.799 + msgAng->set_z(vec.z);
6.800 +
6.801 + return true;
6.802 + }
6.803 +
6.804 + inline bool GetMessage(const char *pszFieldName, protobuf::Message **message)
6.805 + {
6.806 + GETCHECK_FIELD();
6.807 + CHECK_FIELD_TYPE(MESSAGE);
6.808 + CHECK_FIELD_NOT_REPEATED();
6.809 +
6.810 + *message = msg->GetReflection()->MutableMessage(msg, field);
6.811 +
6.812 + return true;
6.813 + }
6.814 +
6.815 + inline bool GetRepeatedMessage(const char *pszFieldName, int index, const protobuf::Message **message)
6.816 + {
6.817 + GETCHECK_FIELD();
6.818 + CHECK_FIELD_TYPE(MESSAGE);
6.819 + CHECK_FIELD_REPEATED();
6.820 + CHECK_REPEATED_ELEMENT(index);
6.821 +
6.822 + const protobuf::Message *m = &msg->GetReflection()->GetRepeatedMessage(*msg, field, index);
6.823 + *message = m;
6.824 +
6.825 + return true;
6.826 + }
6.827 +
6.828 + inline bool AddMessage(const char *pszFieldName, protobuf::Message **message)
6.829 + {
6.830 + GETCHECK_FIELD();
6.831 + CHECK_FIELD_TYPE(MESSAGE);
6.832 + CHECK_FIELD_REPEATED();
6.833 +
6.834 + *message = msg->GetReflection()->AddMessage(msg, field);
6.835 +
6.836 + return true;
6.837 + }
6.838 +
6.839 + inline int GetRepeatedFieldCount(const char *pszFieldName)
6.840 + {
6.841 + const protobuf::FieldDescriptor *field = msg->GetDescriptor()->FindFieldByName(pszFieldName); \
6.842 + if (!field)
6.843 + return -1;
6.844 +
6.845 + if (field->label() != protobuf::FieldDescriptor::LABEL_REPEATED)
6.846 + return -1;
6.847 +
6.848 + return msg->GetReflection()->FieldSize(*msg, field);
6.849 + }
6.850 +
6.851 +private:
6.852 + protobuf::Message *msg;
6.853 + PBHandleList childHandles;
6.854 +};
6.855 +
6.856 +#endif // _INCLUDE_SOURCEMOD_SMPBMESSAGE_H_
7.1 --- a/core/UserMessages.cpp Mon Jan 07 09:09:14 2013 -0500
7.2 +++ b/core/UserMessages.cpp Tue Jan 22 21:43:12 2013 -0500
7.3 @@ -32,18 +32,32 @@
7.4 #include "UserMessages.h"
7.5 #include "sm_stringutil.h"
7.6
7.7 +#if SOURCE_ENGINE == SE_CSGO
7.8 +#include <cstrike15_usermessage_helpers.h>
7.9 +#endif
7.10 +
7.11 UserMessages g_UserMsgs;
7.12
7.13 +#if SOURCE_ENGINE == SE_CSGO
7.14 +SH_DECL_HOOK3_void(IVEngineServer, SendUserMessage, SH_NOATTRIB, 0, IRecipientFilter &, int, const protobuf::Message &);
7.15 +#else
7.16 #if SOURCE_ENGINE >= SE_LEFT4DEAD
7.17 SH_DECL_HOOK3(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write *, IRecipientFilter *, int, const char *);
7.18 #else
7.19 SH_DECL_HOOK2(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write *, IRecipientFilter *, int);
7.20 #endif
7.21 SH_DECL_HOOK0_void(IVEngineServer, MessageEnd, SH_NOATTRIB, 0);
7.22 +#endif // ==SE_CSGO
7.23
7.24 -UserMessages::UserMessages() : m_InterceptBuffer(m_pBase, 2500)
7.25 +UserMessages::UserMessages()
7.26 +#ifndef USE_PROTOBUF_USERMESSAGES
7.27 + : m_InterceptBuffer(m_pBase, 2500)
7.28 {
7.29 m_Names = sm_trie_create();
7.30 +#else
7.31 + : m_InterceptBuffer(NULL)
7.32 +{
7.33 +#endif
7.34 m_HookCount = 0;
7.35 m_InExec = false;
7.36 m_InHook = false;
7.37 @@ -53,7 +67,9 @@
7.38
7.39 UserMessages::~UserMessages()
7.40 {
7.41 +#ifndef USE_PROTOBUF_USERMESSAGES
7.42 sm_trie_destroy(m_Names);
7.43 +#endif
7.44
7.45 CStack<ListenerInfo *>::iterator iter;
7.46 for (iter=m_FreeListeners.begin(); iter!=m_FreeListeners.end(); iter++)
7.47 @@ -65,8 +81,10 @@
7.48
7.49 void UserMessages::OnSourceModStartup(bool late)
7.50 {
7.51 +#ifndef USE_PROTOBUF_USERMESSAGES
7.52 /* -1 means SourceMM was unable to get the user message list */
7.53 m_FallbackSearch = (g_SMAPI->GetUserMessageCount() == -1);
7.54 +#endif
7.55 }
7.56
7.57 void UserMessages::OnSourceModAllInitialized()
7.58 @@ -78,16 +96,25 @@
7.59 {
7.60 if (m_HookCount)
7.61 {
7.62 +#if SOURCE_ENGINE == SE_CSGO
7.63 + SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Pre, false);
7.64 + SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Post, true);
7.65 +#else
7.66 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Pre, false);
7.67 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Post, true);
7.68 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Pre, false);
7.69 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Post, true);
7.70 +#endif
7.71 }
7.72 m_HookCount = 0;
7.73 }
7.74
7.75 int UserMessages::GetMessageIndex(const char *msg)
7.76 {
7.77 +#if SOURCE_ENGINE == SE_CSGO
7.78 + // Can split this per engine and/or game later
7.79 + return g_Cstrike15UsermessageHelpers.GetIndex(msg);
7.80 +#else
7.81 int msgid;
7.82
7.83 if (!sm_trie_retrieve(m_Names, msg, reinterpret_cast<void **>(&msgid)))
7.84 @@ -118,10 +145,19 @@
7.85 }
7.86
7.87 return msgid;
7.88 +#endif
7.89 }
7.90
7.91 bool UserMessages::GetMessageName(int msgid, char *buffer, size_t maxlength) const
7.92 {
7.93 +#if SOURCE_ENGINE == SE_CSGO
7.94 + const char *pszName = g_Cstrike15UsermessageHelpers.GetName(msgid);
7.95 + if (!pszName)
7.96 + return false;
7.97 +
7.98 + strncopy(buffer, pszName, maxlength);
7.99 + return true;
7.100 +#else
7.101 if (m_FallbackSearch)
7.102 {
7.103 int size;
7.104 @@ -137,10 +173,14 @@
7.105 }
7.106
7.107 return false;
7.108 +#endif
7.109 }
7.110
7.111 -bf_write *UserMessages::StartMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags)
7.112 +bf_write *UserMessages::StartBitBufMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags)
7.113 {
7.114 +#ifdef USE_PROTOBUF_USERMESSAGES
7.115 + return NULL;
7.116 +#else
7.117 bf_write *buffer;
7.118
7.119 if (m_InExec || m_InHook)
7.120 @@ -182,6 +222,68 @@
7.121 }
7.122
7.123 return buffer;
7.124 +#endif // USE_PROTOBUF_USERMESSAGES
7.125 +}
7.126 +
7.127 +google::protobuf::Message *UserMessages::StartProtobufMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags)
7.128 +{
7.129 +#ifndef USE_PROTOBUF_USERMESSAGES
7.130 + return NULL;
7.131 +#else
7.132 + protobuf::Message *buffer;
7.133 +
7.134 + if (m_InExec || m_InHook)
7.135 + {
7.136 + return NULL;
7.137 + }
7.138 + if (msg_id < 0 || msg_id >= 255)
7.139 + {
7.140 + return NULL;
7.141 + }
7.142 +
7.143 + m_CurId = msg_id;
7.144 + m_CellRecFilter.Initialize(players, playersNum);
7.145 +
7.146 + m_CurFlags = flags;
7.147 + if (m_CurFlags & USERMSG_INITMSG)
7.148 + {
7.149 + m_CellRecFilter.SetToInit(true);
7.150 + }
7.151 + if (m_CurFlags & USERMSG_RELIABLE)
7.152 + {
7.153 + m_CellRecFilter.SetToReliable(true);
7.154 + }
7.155 +
7.156 + m_InExec = true;
7.157 +
7.158 + if (m_CurFlags & USERMSG_BLOCKHOOKS)
7.159 + {
7.160 + // direct message creation, return buffer "from engine". keep track
7.161 + m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_id)->New();
7.162 + buffer = m_FakeEngineBuffer;
7.163 + } else {
7.164 + protobuf::Message *msg = OnStartMessage_Pre(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id, g_SMAPI->GetUserMessage(msg_id));
7.165 + switch (m_FakeMetaRes)
7.166 + {
7.167 + case MRES_IGNORED:
7.168 + case MRES_HANDLED:
7.169 + m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_id)->New();
7.170 + buffer = m_FakeEngineBuffer;
7.171 + break;
7.172 +
7.173 + case MRES_OVERRIDE:
7.174 + m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_id)->New();
7.175 + // fallthrough
7.176 + case MRES_SUPERCEDE:
7.177 + buffer = msg;
7.178 + break;
7.179 + }
7.180 +
7.181 + OnStartMessage_Post(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id, g_SMAPI->GetUserMessage(msg_id));
7.182 + }
7.183 +
7.184 + return buffer;
7.185 +#endif // USE_PROTOBUF_USERMESSAGES
7.186 }
7.187
7.188 bool UserMessages::EndMessage()
7.189 @@ -191,12 +293,37 @@
7.190 return false;
7.191 }
7.192
7.193 +#if SOURCE_ENGINE == SE_CSGO
7.194 + if (m_CurFlags & USERMSG_BLOCKHOOKS)
7.195 + {
7.196 + ENGINE_CALL(SendUserMessage)(static_cast<IRecipientFilter &>(m_CellRecFilter), m_CurId, *m_FakeEngineBuffer);
7.197 + delete m_FakeEngineBuffer;
7.198 + m_FakeEngineBuffer = NULL;
7.199 + } else {
7.200 + OnMessageEnd_Pre();
7.201 +
7.202 + switch (m_FakeMetaRes)
7.203 + {
7.204 + case MRES_IGNORED:
7.205 + case MRES_HANDLED:
7.206 + case MRES_OVERRIDE:
7.207 + engine->SendUserMessage(static_cast<IRecipientFilter &>(m_CellRecFilter), m_CurId, *m_FakeEngineBuffer);
7.208 + delete m_FakeEngineBuffer;
7.209 + m_FakeEngineBuffer = NULL;
7.210 + break;
7.211 + //case MRES_SUPERCEDE:
7.212 + }
7.213 +
7.214 + OnMessageEnd_Post();
7.215 + }
7.216 +#else
7.217 if (m_CurFlags & USERMSG_BLOCKHOOKS)
7.218 {
7.219 ENGINE_CALL(MessageEnd)();
7.220 } else {
7.221 engine->MessageEnd();
7.222 }
7.223 +#endif // SE_CSGO
7.224
7.225 m_InExec = false;
7.226 m_CurFlags = 0;
7.227 @@ -205,31 +332,60 @@
7.228 return true;
7.229 }
7.230
7.231 +UserMessageType UserMessages::GetUserMessageType() const
7.232 +{
7.233 +#ifdef USE_PROTOBUF_USERMESSAGES
7.234 + return UM_Protobuf;
7.235 +#else
7.236 + return UM_BitBuf;
7.237 +#endif
7.238 +}
7.239 +
7.240 bool UserMessages::HookUserMessage2(int msg_id,
7.241 IUserMessageListener *pListener,
7.242 bool intercept)
7.243 {
7.244 - return InternalHook(msg_id, pListener, intercept, true);
7.245 +#ifdef USE_PROTOBUF_USERMESSAGES
7.246 + return InternalHook(msg_id, (IProtobufUserMessageListener *)pListener, intercept, true);
7.247 +#else
7.248 + return InternalHook(msg_id, (IBitBufUserMessageListener *)pListener, intercept, true);
7.249 +#endif
7.250 }
7.251
7.252 bool UserMessages::UnhookUserMessage2(int msg_id,
7.253 IUserMessageListener *pListener,
7.254 bool intercept)
7.255 {
7.256 - return InternalUnhook(msg_id, pListener, intercept, true);
7.257 +#ifdef USE_PROTOBUF_USERMESSAGES
7.258 + return InternalUnhook(msg_id, (IProtobufUserMessageListener *)pListener, intercept, true);
7.259 +#else
7.260 + return InternalUnhook(msg_id, (IBitBufUserMessageListener *)pListener, intercept, true);
7.261 +#endif
7.262 }
7.263
7.264 bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
7.265 {
7.266 - return InternalHook(msg_id, pListener, intercept, false);
7.267 +#ifdef USE_PROTOBUF_USERMESSAGES
7.268 + return InternalHook(msg_id, (IProtobufUserMessageListener *)pListener, intercept, false);
7.269 +#else
7.270 + return InternalHook(msg_id, (IBitBufUserMessageListener *)pListener, intercept, false);
7.271 +#endif
7.272 }
7.273
7.274 bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
7.275 {
7.276 - return InternalUnhook(msg_id, pListener, intercept, false);
7.277 +#ifdef USE_PROTOBUF_USERMESSAGES
7.278 + return InternalUnhook(msg_id, (IProtobufUserMessageListener *)pListener, intercept, false);
7.279 +#else
7.280 + return InternalUnhook(msg_id, (IBitBufUserMessageListener *)pListener, intercept, false);
7.281 +#endif
7.282 }
7.283
7.284 -bool UserMessages::InternalHook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew)
7.285 +#ifdef USE_PROTOBUF_USERMESSAGES
7.286 +bool UserMessages::InternalHook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew)
7.287 +#else
7.288 +bool UserMessages::InternalHook(int msg_id, IBitBufUserMessageListener *pListener, bool intercept, bool isNew)
7.289 +#endif
7.290 {
7.291 if (msg_id < 0 || msg_id >= 255)
7.292 {
7.293 @@ -252,10 +408,15 @@
7.294
7.295 if (!m_HookCount++)
7.296 {
7.297 +#if SOURCE_ENGINE == SE_CSGO
7.298 + SH_ADD_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Pre, false);
7.299 + SH_ADD_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Post, true);
7.300 +#else
7.301 SH_ADD_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Pre, false);
7.302 SH_ADD_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Post, true);
7.303 SH_ADD_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Pre, false);
7.304 SH_ADD_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Post, true);
7.305 +#endif
7.306 }
7.307
7.308 if (intercept)
7.309 @@ -268,7 +429,11 @@
7.310 return true;
7.311 }
7.312
7.313 -bool UserMessages::InternalUnhook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew)
7.314 +#ifdef USE_PROTOBUF_USERMESSAGES
7.315 +bool UserMessages::InternalUnhook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew)
7.316 +#else
7.317 +bool UserMessages::InternalUnhook(int msg_id, IBitBufUserMessageListener *pListener, bool intercept, bool isNew)
7.318 +#endif
7.319 {
7.320 MsgList *pList;
7.321 MsgIter iter;
7.322 @@ -309,14 +474,167 @@
7.323 {
7.324 if (--m_HookCount == 0)
7.325 {
7.326 +#if SOURCE_ENGINE == SE_CSGO
7.327 + SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Pre, false);
7.328 + SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Post, true);
7.329 +#else
7.330 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Pre, false);
7.331 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Post, true);
7.332 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Pre, false);
7.333 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Post, true);
7.334 +#endif
7.335 }
7.336 }
7.337
7.338 -#if SOURCE_ENGINE >= SE_LEFT4DEAD
7.339 +#ifdef USE_PROTOBUF_USERMESSAGES
7.340 +// Unlike protobuf's Message::CopyFrom:
7.341 +// - Does not require to/from message descriptors to be identical.
7.342 +// - Fields are copied by name, rather than index.
7.343 +// - String fields are retrieved for copy with GetStringReference, to avoid destucting libprotobuf std::string in sm.
7.344 +// - Unknown fields in |from| message are not copied to |to| message.
7.345 +// - Copying Message fields recursively calls this function, rather than Message::MergeFrom.
7.346 +static void _CopyProtobufMessage(const protobuf::Message &from, protobuf::Message *to)
7.347 +{
7.348 + const protobuf::Descriptor* descriptor = from.GetDescriptor();
7.349 +
7.350 + const protobuf::Reflection* from_reflection = from.GetReflection();
7.351 + const protobuf::Reflection* to_reflection = to->GetReflection();
7.352 +
7.353 + protobuf::UnknownFieldSet toUnknownFields;
7.354 +
7.355 + int fromFieldCount = descriptor->field_count();
7.356 + for (int i = 0; i < fromFieldCount; i++)
7.357 + {
7.358 + const protobuf::FieldDescriptor* fromField = descriptor->field(i);
7.359 + const protobuf::FieldDescriptor* toField = to->GetDescriptor()->FindFieldByName(fromField->name());
7.360 +
7.361 + // This will stripped new fields off of intercepted usermessages.
7.362 + // TODO: fix that.
7.363 + if (!toField)
7.364 + {
7.365 + continue;
7.366 + }
7.367 +
7.368 + if (fromField->is_repeated())
7.369 + {
7.370 + int count = from_reflection->FieldSize(from, fromField);
7.371 + for (int j = 0; j < count; j++)
7.372 + {
7.373 + switch (fromField->cpp_type())
7.374 + {
7.375 +#define HANDLE_TYPE(CPPTYPE, METHOD) \
7.376 + case protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \
7.377 + to_reflection->Add##METHOD(to, toField, \
7.378 + from_reflection->GetRepeated##METHOD(from, fromField, j)); \
7.379 + break;
7.380 + HANDLE_TYPE(INT32 , Int32 );
7.381 + HANDLE_TYPE(INT64 , Int64 );
7.382 + HANDLE_TYPE(UINT32, UInt32);
7.383 + HANDLE_TYPE(UINT64, UInt64);
7.384 + HANDLE_TYPE(FLOAT , Float );
7.385 + HANDLE_TYPE(DOUBLE, Double);
7.386 + HANDLE_TYPE(BOOL , Bool );
7.387 + HANDLE_TYPE(ENUM , Enum );
7.388 +#undef HANDLE_TYPE
7.389 + case protobuf::FieldDescriptor::CPPTYPE_STRING:
7.390 + {
7.391 + std::string buffer;
7.392 + to_reflection->AddString(to, toField,
7.393 + from_reflection->GetRepeatedStringReference(from, fromField, j, &buffer));
7.394 + }
7.395 + break;
7.396 + case protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
7.397 + _CopyProtobufMessage(
7.398 + from_reflection->GetRepeatedMessage(from, fromField, j),
7.399 + to_reflection->AddMessage(to, toField)
7.400 + );
7.401 + break;
7.402 + }
7.403 + }
7.404 + }
7.405 + else
7.406 + {
7.407 + switch (fromField->cpp_type())
7.408 + {
7.409 +#define HANDLE_TYPE(CPPTYPE, METHOD) \
7.410 + case protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \
7.411 + to_reflection->Set##METHOD(to, toField, \
7.412 + from_reflection->Get##METHOD(from, fromField)); \
7.413 + break;
7.414 + HANDLE_TYPE(INT32 , Int32 );
7.415 + HANDLE_TYPE(INT64 , Int64 );
7.416 + HANDLE_TYPE(UINT32, UInt32);
7.417 + HANDLE_TYPE(UINT64, UInt64);
7.418 + HANDLE_TYPE(FLOAT , Float );
7.419 + HANDLE_TYPE(DOUBLE, Double);
7.420 + HANDLE_TYPE(BOOL , Bool );
7.421 + HANDLE_TYPE(ENUM , Enum );
7.422 +#undef HANDLE_TYPE
7.423 + case protobuf::FieldDescriptor::CPPTYPE_STRING:
7.424 + {
7.425 + std::string buffer;
7.426 + to_reflection->SetString(to, toField,
7.427 + from_reflection->GetStringReference(from, fromField, &buffer));
7.428 + }
7.429 + break;
7.430 + case protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
7.431 + _CopyProtobufMessage(
7.432 + from_reflection->GetMessage(from, fromField),
7.433 + to_reflection->MutableMessage(to, toField)
7.434 + );
7.435 + break;
7.436 + }
7.437 + }
7.438 + }
7.439 +}
7.440 +#endif
7.441 +
7.442 +#if SOURCE_ENGINE == SE_CSGO
7.443 +void UserMessages::OnSendUserMessage_Pre(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg)
7.444 +{
7.445 + OnStartMessage_Pre(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
7.446 + if (m_FakeMetaRes == MRES_SUPERCEDE)
7.447 + {
7.448 + _CopyProtobufMessage(msg, m_InterceptBuffer);
7.449 + }
7.450 + else
7.451 + {
7.452 + OnStartMessage_Post(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
7.453 + }
7.454 +
7.455 + OnMessageEnd_Pre();
7.456 + if (m_FakeMetaRes == MRES_SUPERCEDE)
7.457 + RETURN_META(MRES_SUPERCEDE);
7.458 +
7.459 + RETURN_META(MRES_IGNORED);
7.460 +}
7.461 +
7.462 +void UserMessages::OnSendUserMessage_Post(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg)
7.463 +{
7.464 + OnMessageEnd_Post();
7.465 + RETURN_META(MRES_IGNORED);
7.466 +}
7.467 +#endif
7.468 +
7.469 +#ifdef USE_PROTOBUF_USERMESSAGES
7.470 +#define UM_RETURN_META_VALUE(res, val) \
7.471 + m_FakeMetaRes = res; \
7.472 + return val;
7.473 +
7.474 +#define UM_RETURN_META(res) \
7.475 + m_FakeMetaRes = res; \
7.476 + return;
7.477 +#else
7.478 +#define UM_RETURN_META_VALUE(res, val) \
7.479 + RETURN_META_VALUE(res, val)
7.480 +
7.481 +#define UM_RETURN_META(res) \
7.482 + RETURN_META(res)
7.483 +#endif
7.484 +
7.485 +#if SOURCE_ENGINE == SE_CSGO
7.486 +protobuf::Message *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
7.487 +#elif SOURCE_ENGINE >= SE_LEFT4DEAD
7.488 bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
7.489 #else
7.490 bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type)
7.491 @@ -329,7 +647,7 @@
7.492 || (m_InExec && (m_CurFlags & USERMSG_BLOCKHOOKS)))
7.493 {
7.494 m_InHook = false;
7.495 - RETURN_META_VALUE(MRES_IGNORED, NULL);
7.496 + UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
7.497 }
7.498
7.499 m_CurId = msg_type;
7.500 @@ -339,14 +657,23 @@
7.501
7.502 if (!is_intercept_empty)
7.503 {
7.504 +#ifdef USE_PROTOBUF_USERMESSAGES
7.505 + if (m_InterceptBuffer)
7.506 + delete m_InterceptBuffer;
7.507 + m_InterceptBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_type)->New();
7.508 + UM_RETURN_META_VALUE(MRES_SUPERCEDE, m_InterceptBuffer);
7.509 +#else
7.510 m_InterceptBuffer.Reset();
7.511 - RETURN_META_VALUE(MRES_SUPERCEDE, &m_InterceptBuffer);
7.512 + UM_RETURN_META_VALUE(MRES_SUPERCEDE, &m_InterceptBuffer);
7.513 +#endif
7.514 }
7.515
7.516 - RETURN_META_VALUE(MRES_IGNORED, NULL);
7.517 + UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
7.518 }
7.519
7.520 -#if SOURCE_ENGINE >= SE_LEFT4DEAD
7.521 +#if SOURCE_ENGINE == SE_CSGO
7.522 +protobuf::Message *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
7.523 +#elif SOURCE_ENGINE >= SE_LEFT4DEAD
7.524 bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
7.525 #else
7.526 bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type)
7.527 @@ -354,19 +681,24 @@
7.528 {
7.529 if (!m_InHook)
7.530 {
7.531 - RETURN_META_VALUE(MRES_IGNORED, NULL);
7.532 + UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
7.533 }
7.534
7.535 +#ifdef USE_PROTOBUF_USERMESSAGES
7.536 + m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_type)->New();
7.537 + m_OrigBuffer = m_FakeEngineBuffer;
7.538 +#else
7.539 m_OrigBuffer = META_RESULT_ORIG_RET(bf_write *);
7.540 +#endif
7.541
7.542 - RETURN_META_VALUE(MRES_IGNORED, NULL);
7.543 + UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
7.544 }
7.545
7.546 void UserMessages::OnMessageEnd_Post()
7.547 {
7.548 if (!m_InHook)
7.549 {
7.550 - RETURN_META(MRES_IGNORED);
7.551 + UM_RETURN_META(MRES_IGNORED);
7.552 }
7.553
7.554 MsgList *pList;
7.555 @@ -434,7 +766,7 @@
7.556 {
7.557 if (!m_InHook)
7.558 {
7.559 - RETURN_META(MRES_IGNORED);
7.560 + UM_RETURN_META(MRES_IGNORED);
7.561 }
7.562
7.563 MsgList *pList;
7.564 @@ -450,7 +782,11 @@
7.565 {
7.566 pInfo = (*iter);
7.567 pInfo->IsHooked = true;
7.568 +#ifdef USE_PROTOBUF_USERMESSAGES
7.569 + res = pInfo->Callback->InterceptUserMessage(m_CurId, m_InterceptBuffer, m_CurRecFilter);
7.570 +#else
7.571 res = pInfo->Callback->InterceptUserMessage(m_CurId, &m_InterceptBuffer, m_CurRecFilter);
7.572 +#endif
7.573
7.574 intercepted = true;
7.575
7.576 @@ -498,8 +834,12 @@
7.577
7.578 if (!handled && intercepted)
7.579 {
7.580 +#if SOURCE_ENGINE == SE_CSGO
7.581 + ENGINE_CALL(SendUserMessage)(static_cast<IRecipientFilter &>(*m_CurRecFilter), m_CurId, *m_InterceptBuffer);
7.582 + delete m_InterceptBuffer;
7.583 + m_InterceptBuffer = NULL;
7.584 +#else
7.585 bf_write *engine_bfw;
7.586 -
7.587 #if SOURCE_ENGINE >= SE_LEFT4DEAD
7.588 engine_bfw = ENGINE_CALL(UserMessageBegin)(m_CurRecFilter, m_CurId, g_SMAPI->GetUserMessage(m_CurId));
7.589 #else
7.590 @@ -508,6 +848,7 @@
7.591 m_ReadBuffer.StartReading(m_InterceptBuffer.GetBasePointer(), m_InterceptBuffer.GetNumBytesWritten());
7.592 engine_bfw->WriteBitsFromBuffer(&m_ReadBuffer, m_InterceptBuffer.GetNumBitsWritten());
7.593 ENGINE_CALL(MessageEnd)();
7.594 +#endif // SE_CSGO
7.595 }
7.596
7.597 pList = &m_msgHooks[m_CurId];
7.598 @@ -529,8 +870,8 @@
7.599 iter++;
7.600 }
7.601
7.602 - RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED);
7.603 + UM_RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED);
7.604 supercede:
7.605 m_BlockEndPost = true;
7.606 - RETURN_META(MRES_SUPERCEDE);
7.607 + UM_RETURN_META(MRES_SUPERCEDE);
7.608 }
8.1 --- a/core/UserMessages.h Mon Jan 07 09:09:14 2013 -0500
8.2 +++ b/core/UserMessages.h Tue Jan 22 21:43:12 2013 -0500
8.3 @@ -36,16 +36,35 @@
8.4 #include <IUserMessages.h>
8.5 #include "sourcemm_api.h"
8.6 #include "sm_trie.h"
8.7 +#include "sm_stringutil.h"
8.8 #include "CellRecipientFilter.h"
8.9
8.10 using namespace SourceHook;
8.11 using namespace SourceMod;
8.12
8.13 +#if SOURCE_ENGINE == SE_CSGO
8.14 +#define USE_PROTOBUF_USERMESSAGES
8.15 +#endif
8.16 +
8.17 +#ifdef USE_PROTOBUF_USERMESSAGES
8.18 +#include <google/protobuf/message.h>
8.19 +#include <google/protobuf/descriptor.h>
8.20 +#include <netmessages.pb.h>
8.21 +
8.22 +using namespace google;
8.23 +#else
8.24 +#include <bitbuf.h>
8.25 +#endif
8.26 +
8.27 #define INVALID_MESSAGE_ID -1
8.28
8.29 struct ListenerInfo
8.30 {
8.31 - IUserMessageListener *Callback;
8.32 +#ifdef USE_PROTOBUF_USERMESSAGES
8.33 + IProtobufUserMessageListener *Callback;
8.34 +#else
8.35 + IBitBufUserMessageListener *Callback;
8.36 +#endif
8.37 bool IsHooked;
8.38 bool KillMe;
8.39 bool IsNew;
8.40 @@ -70,7 +89,8 @@
8.41 bool GetMessageName(int msgid, char *buffer, size_t maxlength) const;
8.42 bool HookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept=false);
8.43 bool UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept=false);
8.44 - bf_write *StartMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags);
8.45 + bf_write *StartBitBufMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags);
8.46 + google::protobuf::Message *StartProtobufMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags);
8.47 bool EndMessage();
8.48 bool HookUserMessage2(int msg_id,
8.49 IUserMessageListener *pListener,
8.50 @@ -78,8 +98,17 @@
8.51 bool UnhookUserMessage2(int msg_id,
8.52 IUserMessageListener *pListener,
8.53 bool intercept=false);
8.54 + UserMessageType GetUserMessageType() const;
8.55 public:
8.56 -#if SOURCE_ENGINE >= SE_LEFT4DEAD
8.57 +#if SOURCE_ENGINE == SE_CSGO
8.58 + void OnSendUserMessage_Pre(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg);
8.59 + void OnSendUserMessage_Post(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg);
8.60 +#endif
8.61 +
8.62 +#if SOURCE_ENGINE == SE_CSGO
8.63 + protobuf::Message *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name);
8.64 + protobuf::Message *OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name);
8.65 +#elif SOURCE_ENGINE >= SE_LEFT4DEAD
8.66 bf_write *OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name);
8.67 bf_write *OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name);
8.68 #else
8.69 @@ -89,8 +118,13 @@
8.70 void OnMessageEnd_Pre();
8.71 void OnMessageEnd_Post();
8.72 private:
8.73 - bool InternalHook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew);
8.74 - bool InternalUnhook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew);
8.75 +#ifdef USE_PROTOBUF_USERMESSAGES
8.76 + bool InternalHook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew);
8.77 + bool InternalUnhook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew);
8.78 +#else
8.79 + bool InternalHook(int msg_id, IBitBufUserMessageListener *pListener, bool intercept, bool isNew);
8.80 + bool InternalUnhook(int msg_id, IBitBufUserMessageListener *pListener, bool intercept, bool isNew);
8.81 +#endif
8.82 void _DecRefCounter();
8.83 private:
8.84 List<ListenerInfo *> m_msgHooks[255];
8.85 @@ -98,15 +132,26 @@
8.86 CStack<ListenerInfo *> m_FreeListeners;
8.87 unsigned char m_pBase[2500];
8.88 IRecipientFilter *m_CurRecFilter;
8.89 +#ifndef USE_PROTOBUF_USERMESSAGES
8.90 bf_write m_InterceptBuffer;
8.91 bf_write *m_OrigBuffer;
8.92 bf_read m_ReadBuffer;
8.93 +#else
8.94 + // The engine used to provide this. Now we track it.
8.95 + protobuf::Message *m_OrigBuffer;
8.96 + protobuf::Message *m_FakeEngineBuffer;
8.97 + META_RES m_FakeMetaRes;
8.98 +
8.99 + protobuf::Message *m_InterceptBuffer;
8.100 +#endif
8.101 size_t m_HookCount;
8.102 bool m_InHook;
8.103 bool m_BlockEndPost;
8.104 +#ifndef USE_PROTOBUF_USERMESSAGES
8.105 bool m_FallbackSearch;
8.106
8.107 Trie *m_Names;
8.108 +#endif
8.109 CellRecipientFilter m_CellRecFilter;
8.110 bool m_InExec;
8.111 int m_CurFlags;
9.1 --- a/core/smn_bitbuffer.cpp Mon Jan 07 09:09:14 2013 -0500
9.2 +++ b/core/smn_bitbuffer.cpp Tue Jan 22 21:43:12 2013 -0500
9.3 @@ -29,11 +29,16 @@
9.4 * Version: $Id$
9.5 */
9.6
9.7 +#include "UserMessages.h"
9.8 +
9.9 +#ifndef USE_PROTOBUF_USERMESSAGES
9.10 +
9.11 #include "sourcemod.h"
9.12 #include "HandleSys.h"
9.13 #include <bitbuf.h>
9.14 #include <vector.h>
9.15 #include <HalfLife2.h>
9.16 +#include "smn_usermsgs.h"
9.17
9.18 static cell_t smn_BfWriteBool(IPluginContext *pCtx, const cell_t *params)
9.19 {
9.20 @@ -713,3 +718,5 @@
9.21 {"BfGetNumBytesLeft", smn_BfGetNumBytesLeft},
9.22 {NULL, NULL}
9.23 };
9.24 +
9.25 +#endif
10.1 --- a/core/smn_console.cpp Mon Jan 07 09:09:14 2013 -0500
10.2 +++ b/core/smn_console.cpp Tue Jan 22 21:43:12 2013 -0500
10.3 @@ -48,6 +48,10 @@
10.4 #include "ConsoleDetours.h"
10.5 #include "ConCommandBaseIterator.h"
10.6
10.7 +#if SOURCE_ENGINE == SE_CSGO
10.8 +#include <netmessages.pb.h>
10.9 +#endif
10.10 +
10.11 #if SOURCE_ENGINE >= SE_EYE
10.12 #define NETMSG_BITS 6
10.13 #else
10.14 @@ -1427,10 +1431,22 @@
10.15 char data[256];
10.16 bf_write buffer(data, sizeof(data));
10.17
10.18 +#if SOURCE_ENGINE == SE_CSGO
10.19 + CNETMsg_SetConVar msg;
10.20 + CMsg_CVars_CVar *cvar = msg.mutable_convars()->add_cvars();
10.21 +
10.22 + cvar->set_name(pConVar->GetName());
10.23 + cvar->set_value(value);
10.24 +
10.25 + buffer.WriteVarInt32(net_SetConVar);
10.26 + buffer.WriteVarInt32(msg.ByteSize());
10.27 + msg.SerializeWithCachedSizesToArray( (uint8 *)( buffer.GetBasePointer() + buffer.GetNumBytesWritten() ) );
10.28 +#else
10.29 buffer.WriteUBitLong(NET_SETCONVAR, NETMSG_BITS);
10.30 buffer.WriteByte(1);
10.31 buffer.WriteString(pConVar->GetName());
10.32 buffer.WriteString(value);
10.33 +#endif
10.34
10.35 CPlayer *pPlayer = g_Players.GetPlayerByIndex(params[1]);
10.36
11.1 --- a/core/smn_hudtext.cpp Mon Jan 07 09:09:14 2013 -0500
11.2 +++ b/core/smn_hudtext.cpp Tue Jan 22 21:43:12 2013 -0500
11.3 @@ -37,6 +37,10 @@
11.4 #include "HandleSys.h"
11.5 #include "logic_bridge.h"
11.6
11.7 +#if SOURCE_ENGINE == SE_CSGO
11.8 +#include <game/shared/csgo/protobuf/cstrike15_usermessages.pb.h>
11.9 +#endif
11.10 +
11.11 #define MAX_HUD_CHANNELS 6
11.12
11.13 int g_HudMsgNum = -1;
11.14 @@ -308,12 +312,39 @@
11.15
11.16 void UTIL_SendHudText(int client, const hud_text_parms &textparms, const char *pMessage)
11.17 {
11.18 - bf_write *bf;
11.19 cell_t players[1];
11.20
11.21 players[0] = client;
11.22
11.23 - bf = g_UserMsgs.StartMessage(g_HudMsgNum, players, 1, 0);
11.24 +#if SOURCE_ENGINE == SE_CSGO
11.25 + // If or when we need to support multiple games per engine with this, we can switch to reflection
11.26 + CCSUsrMsg_HudMsg *msg = (CCSUsrMsg_HudMsg *)g_UserMsgs.StartProtobufMessage(g_HudMsgNum, players, 1, 0);
11.27 + msg->set_channel(textparms.channel & 0xFF);
11.28 +
11.29 + CMsgVector2D *pos = msg->mutable_pos();
11.30 + pos->set_x(textparms.x);
11.31 + pos->set_y(textparms.y);
11.32 +
11.33 + CMsgRGBA *color1 = msg->mutable_clr1();
11.34 + color1->set_r(textparms.r1);
11.35 + color1->set_g(textparms.g1);
11.36 + color1->set_b(textparms.b1);
11.37 + color1->set_a(textparms.a1);
11.38 +
11.39 + CMsgRGBA *color2 = msg->mutable_clr2();
11.40 + color2->set_r(textparms.r2);
11.41 + color2->set_g(textparms.g2);
11.42 + color2->set_b(textparms.b2);
11.43 + color2->set_a(textparms.a2);
11.44 +
11.45 + msg->set_effect(textparms.effect);
11.46 + msg->set_fade_in_time(textparms.fadeinTime);
11.47 + msg->set_fade_out_time(textparms.fadeoutTime);
11.48 + msg->set_hold_time(textparms.holdTime);
11.49 + msg->set_fx_time(textparms.fxTime);
11.50 + msg->set_text(pMessage);
11.51 +#else
11.52 + bf_write *bf = g_UserMsgs.StartBitBufMessage(g_HudMsgNum, players, 1, 0);
11.53 bf->WriteByte(textparms.channel & 0xFF );
11.54 bf->WriteFloat(textparms.x);
11.55 bf->WriteFloat(textparms.y);
11.56 @@ -331,6 +362,7 @@
11.57 bf->WriteFloat(textparms.holdTime);
11.58 bf->WriteFloat(textparms.fxTime);
11.59 bf->WriteString(pMessage);
11.60 +#endif
11.61 g_UserMsgs.EndMessage();
11.62 }
11.63
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/core/smn_protobuf.cpp Tue Jan 22 21:43:12 2013 -0500
12.3 @@ -0,0 +1,823 @@
12.4 +/**
12.5 + * vim: set ts=4 :
12.6 + * =============================================================================
12.7 + * SourceMod
12.8 + * Copyright (C) 2013 AlliedModders LLC. All rights reserved.
12.9 + * =============================================================================
12.10 + *
12.11 + * This program is free software; you can redistribute it and/or modify it under
12.12 + * the terms of the GNU General Public License, version 3.0, as published by the
12.13 + * Free Software Foundation.
12.14 + *
12.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
12.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12.18 + * details.
12.19 + *
12.20 + * You should have received a copy of the GNU General Public License along with
12.21 + * this program. If not, see <http://www.gnu.org/licenses/>.
12.22 + *
12.23 + * As a special exception, AlliedModders LLC gives you permission to link the
12.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
12.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
12.26 + * by the Valve Corporation. You must obey the GNU General Public License in
12.27 + * all respects for all other code used. Additionally, AlliedModders LLC grants
12.28 + * this exception to all derivative works. AlliedModders LLC defines further
12.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
12.30 + * or <http://www.sourcemod.net/license.php>.
12.31 + *
12.32 + * Version: $Id$
12.33 + */
12.34 +
12.35 +#include "UserMessages.h"
12.36 +
12.37 +#ifdef USE_PROTOBUF_USERMESSAGES
12.38 +
12.39 +#include "HandleSys.h"
12.40 +#include "UserMessagePBHelpers.h"
12.41 +#include "smn_usermsgs.h"
12.42 +
12.43 +// Assumes pbuf message handle is param 1, gets message as msg
12.44 +#define GET_MSG_FROM_HANDLE_OR_ERR() \
12.45 + Handle_t hndl = static_cast<Handle_t>(params[1]); \
12.46 + HandleError herr; \
12.47 + HandleSecurity sec; \
12.48 + SMProtobufMessage *msg; \
12.49 + \
12.50 + sec.pOwner = NULL; \
12.51 + sec.pIdentity = g_pCoreIdent; \
12.52 + \
12.53 + if ((herr=g_HandleSys.ReadHandle(hndl, g_ProtobufType, &sec, (void **)&msg)) \
12.54 + != HandleError_None) \
12.55 + { \
12.56 + return pCtx->ThrowNativeError("Invalid protobuf message handle %x (error %d)", hndl, herr); \
12.57 + }
12.58 +
12.59 +// Assumes message field name is param 2, gets as strField
12.60 +#define GET_FIELD_NAME_OR_ERR() \
12.61 + int err; \
12.62 + char *strField; \
12.63 + if ((err=pCtx->LocalToString(params[2], &strField)) != SP_ERROR_NONE) \
12.64 + { \
12.65 + pCtx->ThrowNativeErrorEx(err, NULL); \
12.66 + return 0; \
12.67 + }
12.68 +
12.69 +static cell_t smn_PbReadInt(IPluginContext *pCtx, const cell_t *params)
12.70 +{
12.71 + GET_MSG_FROM_HANDLE_OR_ERR();
12.72 + GET_FIELD_NAME_OR_ERR();
12.73 +
12.74 + int ret;
12.75 + if (!msg->GetInt32OrUnsigned(strField, &ret))
12.76 + {
12.77 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.78 + }
12.79 +
12.80 + return ret;
12.81 +}
12.82 +
12.83 +static cell_t smn_PbReadFloat(IPluginContext *pCtx, const cell_t *params)
12.84 +{
12.85 + GET_MSG_FROM_HANDLE_OR_ERR();
12.86 + GET_FIELD_NAME_OR_ERR();
12.87 +
12.88 + float ret;
12.89 + if (!msg->GetFloatOrDouble(strField, &ret))
12.90 + {
12.91 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.92 + }
12.93 +
12.94 + return sp_ftoc(ret);
12.95 +}
12.96 +
12.97 +static cell_t smn_PbReadBool(IPluginContext *pCtx, const cell_t *params)
12.98 +{
12.99 + GET_MSG_FROM_HANDLE_OR_ERR();
12.100 + GET_FIELD_NAME_OR_ERR();
12.101 +
12.102 + bool ret;
12.103 + if (!msg->GetBool(strField, &ret))
12.104 + {
12.105 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.106 + }
12.107 +
12.108 + return ret ? 1 : 0;
12.109 +}
12.110 +
12.111 +static cell_t smn_PbReadString(IPluginContext *pCtx, const cell_t *params)
12.112 +{
12.113 + GET_MSG_FROM_HANDLE_OR_ERR();
12.114 + GET_FIELD_NAME_OR_ERR();
12.115 +
12.116 + char *buf;
12.117 + pCtx->LocalToPhysAddr(params[3], (cell_t **)&buf);
12.118 +
12.119 + if (!msg->GetString(strField, buf, params[4]))
12.120 + {
12.121 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.122 + }
12.123 +
12.124 + return 1;
12.125 +}
12.126 +
12.127 +static cell_t smn_PbReadColor(IPluginContext *pCtx, const cell_t *params)
12.128 +{
12.129 + GET_MSG_FROM_HANDLE_OR_ERR();
12.130 + GET_FIELD_NAME_OR_ERR();
12.131 +
12.132 + cell_t *out;
12.133 + pCtx->LocalToPhysAddr(params[3], &out);
12.134 +
12.135 + Color clr;
12.136 + if (!msg->GetColor(strField, &clr))
12.137 + {
12.138 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.139 + }
12.140 +
12.141 + out[0] = clr.r();
12.142 + out[1] = clr.g();
12.143 + out[2] = clr.b();
12.144 + out[3] = clr.a();
12.145 +
12.146 + return 1;
12.147 +}
12.148 +
12.149 +static cell_t smn_PbReadAngle(IPluginContext *pCtx, const cell_t *params)
12.150 +{
12.151 + GET_MSG_FROM_HANDLE_OR_ERR();
12.152 + GET_FIELD_NAME_OR_ERR();
12.153 +
12.154 + cell_t *out;
12.155 + pCtx->LocalToPhysAddr(params[3], &out);
12.156 +
12.157 + QAngle ang;
12.158 + if (!msg->GetQAngle(strField, &ang))
12.159 + {
12.160 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.161 + }
12.162 +
12.163 + out[0] = sp_ftoc(ang.x);
12.164 + out[1] = sp_ftoc(ang.y);
12.165 + out[2] = sp_ftoc(ang.z);
12.166 +
12.167 + return 1;
12.168 +}
12.169 +
12.170 +static cell_t smn_PbReadVector(IPluginContext *pCtx, const cell_t *params)
12.171 +{
12.172 + GET_MSG_FROM_HANDLE_OR_ERR();
12.173 + GET_FIELD_NAME_OR_ERR();
12.174 +
12.175 + cell_t *out;
12.176 + pCtx->LocalToPhysAddr(params[3], &out);
12.177 +
12.178 + Vector vec;
12.179 + if (!msg->GetVector(strField, &vec))
12.180 + {
12.181 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.182 + }
12.183 +
12.184 + out[0] = sp_ftoc(vec.x);
12.185 + out[1] = sp_ftoc(vec.y);
12.186 + out[2] = sp_ftoc(vec.z);
12.187 +
12.188 + return 1;
12.189 +}
12.190 +
12.191 +static cell_t smn_PbReadVector2D(IPluginContext *pCtx, const cell_t *params)
12.192 +{
12.193 + GET_MSG_FROM_HANDLE_OR_ERR();
12.194 + GET_FIELD_NAME_OR_ERR();
12.195 +
12.196 + cell_t *out;
12.197 + pCtx->LocalToPhysAddr(params[3], &out);
12.198 +
12.199 + Vector2D vec;
12.200 + if (!msg->GetVector2D(strField, &vec))
12.201 + {
12.202 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.203 + }
12.204 +
12.205 + out[0] = sp_ftoc(vec.x);
12.206 + out[1] = sp_ftoc(vec.y);
12.207 +
12.208 + return 1;
12.209 +}
12.210 +
12.211 +static cell_t smn_PbGetRepeatedFieldCount(IPluginContext *pCtx, const cell_t *params)
12.212 +{
12.213 + GET_MSG_FROM_HANDLE_OR_ERR();
12.214 + GET_FIELD_NAME_OR_ERR();
12.215 +
12.216 + int cnt = msg->GetRepeatedFieldCount(strField);
12.217 + if (cnt == -1)
12.218 + {
12.219 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.220 + }
12.221 +
12.222 + return cnt;
12.223 +}
12.224 +
12.225 +static cell_t smn_PbReadRepeatedInt(IPluginContext *pCtx, const cell_t *params)
12.226 +{
12.227 + GET_MSG_FROM_HANDLE_OR_ERR();
12.228 + GET_FIELD_NAME_OR_ERR();
12.229 +
12.230 + int ret;
12.231 + if (!msg->GetRepeatedInt32OrUnsigned(strField, params[3], &ret))
12.232 + {
12.233 + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName());
12.234 + }
12.235 +
12.236 + return ret;
12.237 +}
12.238 +
12.239 +static cell_t smn_PbReadRepeatedFloat(IPluginContext *pCtx, const cell_t *params)
12.240 +{
12.241 + GET_MSG_FROM_HANDLE_OR_ERR();
12.242 + GET_FIELD_NAME_OR_ERR();
12.243 +
12.244 + float ret;
12.245 + if (!msg->GetRepeatedFloatOrDouble(strField, params[3], &ret))
12.246 + {
12.247 + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName());
12.248 + }
12.249 +
12.250 + return sp_ftoc(ret);
12.251 +}
12.252 +
12.253 +static cell_t smn_PbReadRepeatedBool(IPluginContext *pCtx, const cell_t *params)
12.254 +{
12.255 + GET_MSG_FROM_HANDLE_OR_ERR();
12.256 + GET_FIELD_NAME_OR_ERR();
12.257 +
12.258 + bool ret;
12.259 + if (!msg->GetRepeatedBool(strField, params[3], &ret))
12.260 + {
12.261 + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName());
12.262 + }
12.263 +
12.264 + return ret ? 1 : 0;
12.265 +}
12.266 +
12.267 +static cell_t smn_PbReadRepeatedString(IPluginContext *pCtx, const cell_t *params)
12.268 +{
12.269 + GET_MSG_FROM_HANDLE_OR_ERR();
12.270 + GET_FIELD_NAME_OR_ERR();
12.271 +
12.272 + char *buf;
12.273 + pCtx->LocalToPhysAddr(params[4], (cell_t **)&buf);
12.274 +
12.275 + if (!msg->GetRepeatedString(strField, params[3], buf, params[5]))
12.276 + {
12.277 + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName());
12.278 + }
12.279 +
12.280 + return 1;
12.281 +}
12.282 +
12.283 +static cell_t smn_PbReadRepeatedColor(IPluginContext *pCtx, const cell_t *params)
12.284 +{
12.285 + GET_MSG_FROM_HANDLE_OR_ERR();
12.286 + GET_FIELD_NAME_OR_ERR();
12.287 +
12.288 + cell_t *out;
12.289 + pCtx->LocalToPhysAddr(params[4], &out);
12.290 +
12.291 + Color clr;
12.292 + if (!msg->GetRepeatedColor(strField, params[3], &clr))
12.293 + {
12.294 + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName());
12.295 + }
12.296 +
12.297 + out[0] = clr.r();
12.298 + out[1] = clr.g();
12.299 + out[2] = clr.b();
12.300 + out[3] = clr.a();
12.301 +
12.302 + return 1;
12.303 +}
12.304 +
12.305 +static cell_t smn_PbReadRepeatedAngle(IPluginContext *pCtx, const cell_t *params)
12.306 +{
12.307 + GET_MSG_FROM_HANDLE_OR_ERR();
12.308 + GET_FIELD_NAME_OR_ERR();
12.309 +
12.310 + cell_t *out;
12.311 + pCtx->LocalToPhysAddr(params[4], &out);
12.312 +
12.313 + QAngle ang;
12.314 + if (!msg->GetRepeatedQAngle(strField, params[3], &ang))
12.315 + {
12.316 + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName());
12.317 + }
12.318 +
12.319 + out[0] = sp_ftoc(ang.x);
12.320 + out[1] = sp_ftoc(ang.y);
12.321 + out[2] = sp_ftoc(ang.z);
12.322 +
12.323 + return 1;
12.324 +}
12.325 +
12.326 +static cell_t smn_PbReadRepeatedVector(IPluginContext *pCtx, const cell_t *params)
12.327 +{
12.328 + GET_MSG_FROM_HANDLE_OR_ERR();
12.329 + GET_FIELD_NAME_OR_ERR();
12.330 +
12.331 + cell_t *out;
12.332 + pCtx->LocalToPhysAddr(params[4], &out);
12.333 +
12.334 + Vector vec;
12.335 + if (!msg->GetRepeatedVector(strField, params[3], &vec))
12.336 + {
12.337 + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName());
12.338 + }
12.339 +
12.340 + out[0] = sp_ftoc(vec.x);
12.341 + out[1] = sp_ftoc(vec.y);
12.342 + out[2] = sp_ftoc(vec.z);
12.343 +
12.344 + return 1;
12.345 +}
12.346 +
12.347 +static cell_t smn_PbReadRepeatedVector2D(IPluginContext *pCtx, const cell_t *params)
12.348 +{
12.349 + GET_MSG_FROM_HANDLE_OR_ERR();
12.350 + GET_FIELD_NAME_OR_ERR();
12.351 +
12.352 + cell_t *out;
12.353 + pCtx->LocalToPhysAddr(params[4], &out);
12.354 +
12.355 + Vector2D vec;
12.356 + if (!msg->GetRepeatedVector2D(strField, params[3], &vec))
12.357 + {
12.358 + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName());
12.359 + }
12.360 +
12.361 + out[0] = sp_ftoc(vec.x);
12.362 + out[1] = sp_ftoc(vec.y);
12.363 +
12.364 + return 1;
12.365 +}
12.366 +
12.367 +static cell_t smn_PbSetInt(IPluginContext *pCtx, const cell_t *params)
12.368 +{
12.369 + GET_MSG_FROM_HANDLE_OR_ERR();
12.370 + GET_FIELD_NAME_OR_ERR();
12.371 +
12.372 + if (!msg->SetInt32OrUnsigned(strField, params[3]))
12.373 + {
12.374 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.375 + }
12.376 +
12.377 + return 1;
12.378 +}
12.379 +
12.380 +static cell_t smn_PbSetFloat(IPluginContext *pCtx, const cell_t *params)
12.381 +{
12.382 + GET_MSG_FROM_HANDLE_OR_ERR();
12.383 + GET_FIELD_NAME_OR_ERR();
12.384 +
12.385 + if (!msg->SetFloatOrDouble(strField, sp_ctof(params[3])))
12.386 + {
12.387 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.388 + }
12.389 +
12.390 + return 1;
12.391 +}
12.392 +
12.393 +static cell_t smn_PbSetBool(IPluginContext *pCtx, const cell_t *params)
12.394 +{
12.395 + GET_MSG_FROM_HANDLE_OR_ERR();
12.396 + GET_FIELD_NAME_OR_ERR();
12.397 +
12.398 + bool value = (params[3] == 0 ? false : true);
12.399 + if (!msg->SetBool(strField, value))
12.400 + {
12.401 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.402 + }
12.403 +
12.404 + return 1;
12.405 +}
12.406 +
12.407 +static cell_t smn_PbSetString(IPluginContext *pCtx, const cell_t *params)
12.408 +{
12.409 + GET_MSG_FROM_HANDLE_OR_ERR();
12.410 + GET_FIELD_NAME_OR_ERR();
12.411 +
12.412 + char *strValue;
12.413 + if ((err=pCtx->LocalToString(params[3], &strValue)) != SP_ERROR_NONE)
12.414 + {
12.415 + pCtx->ThrowNativeErrorEx(err, NULL);
12.416 + return 0;
12.417 + }
12.418 +
12.419 + if (!msg->SetString(strField, strValue))
12.420 + {
12.421 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.422 + }
12.423 +
12.424 + return 1;
12.425 +}
12.426 +
12.427 +static cell_t smn_PbSetColor(IPluginContext *pCtx, const cell_t *params)
12.428 +{
12.429 + GET_MSG_FROM_HANDLE_OR_ERR();
12.430 + GET_FIELD_NAME_OR_ERR();
12.431 +
12.432 + cell_t *clrParams;
12.433 + if ((err=pCtx->LocalToPhysAddr(params[3], &clrParams)) != SP_ERROR_NONE)
12.434 + {
12.435 + pCtx->ThrowNativeErrorEx(err, NULL);
12.436 + return 0;
12.437 + }
12.438 +
12.439 + Color clr(
12.440 + clrParams[0],
12.441 + clrParams[1],
12.442 + clrParams[2],
12.443 + clrParams[3]);
12.444 +
12.445 + if (!msg->SetColor(strField, clr))
12.446 + {
12.447 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.448 + }
12.449 +
12.450 + return 1;
12.451 +}
12.452 +
12.453 +static cell_t smn_PbSetAngle(IPluginContext *pCtx, const cell_t *params)
12.454 +{
12.455 + GET_MSG_FROM_HANDLE_OR_ERR();
12.456 + GET_FIELD_NAME_OR_ERR();
12.457 +
12.458 + cell_t *angParams;
12.459 + if ((err=pCtx->LocalToPhysAddr(params[3], &angParams)) != SP_ERROR_NONE)
12.460 + {
12.461 + pCtx->ThrowNativeErrorEx(err, NULL);
12.462 + return 0;
12.463 + }
12.464 +
12.465 + QAngle ang(
12.466 + sp_ctof(angParams[0]),
12.467 + sp_ctof(angParams[1]),
12.468 + sp_ctof(angParams[2]));
12.469 +
12.470 + if (!msg->SetQAngle(strField, ang))
12.471 + {
12.472 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.473 + }
12.474 +
12.475 + return 1;
12.476 +}
12.477 +
12.478 +static cell_t smn_PbSetVector(IPluginContext *pCtx, const cell_t *params)
12.479 +{
12.480 + GET_MSG_FROM_HANDLE_OR_ERR();
12.481 + GET_FIELD_NAME_OR_ERR();
12.482 +
12.483 + cell_t *vecParams;
12.484 + if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
12.485 + {
12.486 + pCtx->ThrowNativeErrorEx(err, NULL);
12.487 + return 0;
12.488 + }
12.489 +
12.490 + Vector vec(
12.491 + sp_ctof(vecParams[0]),
12.492 + sp_ctof(vecParams[1]),
12.493 + sp_ctof(vecParams[2]));
12.494 +
12.495 + if (!msg->SetVector(strField, vec))
12.496 + {
12.497 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.498 + }
12.499 +
12.500 + return 1;
12.501 +}
12.502 +
12.503 +static cell_t smn_PbSetVector2D(IPluginContext *pCtx, const cell_t *params)
12.504 +{
12.505 + GET_MSG_FROM_HANDLE_OR_ERR();
12.506 + GET_FIELD_NAME_OR_ERR();
12.507 +
12.508 + cell_t *vecParams;
12.509 + if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
12.510 + {
12.511 + pCtx->ThrowNativeErrorEx(err, NULL);
12.512 + return 0;
12.513 + }
12.514 +
12.515 + Vector2D vec(
12.516 + sp_ctof(vecParams[0]),
12.517 + sp_ctof(vecParams[1]));
12.518 +
12.519 + if (!msg->SetVector2D(strField, vec))
12.520 + {
12.521 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.522 + }
12.523 +
12.524 + return 1;
12.525 +}
12.526 +
12.527 +static cell_t smn_PbAddInt(IPluginContext *pCtx, const cell_t *params)
12.528 +{
12.529 + GET_MSG_FROM_HANDLE_OR_ERR();
12.530 + GET_FIELD_NAME_OR_ERR();
12.531 +
12.532 + if (!msg->AddInt32OrUnsigned(strField, params[3]))
12.533 + {
12.534 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.535 + }
12.536 +
12.537 + return 1;
12.538 +}
12.539 +
12.540 +static cell_t smn_PbAddFloat(IPluginContext *pCtx, const cell_t *params)
12.541 +{
12.542 + GET_MSG_FROM_HANDLE_OR_ERR();
12.543 + GET_FIELD_NAME_OR_ERR();
12.544 +
12.545 + if (!msg->AddFloatOrDouble(strField, sp_ctof(params[3])))
12.546 + {
12.547 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.548 + }
12.549 +
12.550 + return 1;
12.551 +}
12.552 +
12.553 +static cell_t smn_PbAddBool(IPluginContext *pCtx, const cell_t *params)
12.554 +{
12.555 + GET_MSG_FROM_HANDLE_OR_ERR();
12.556 + GET_FIELD_NAME_OR_ERR();
12.557 +
12.558 + bool value = (params[3] == 0 ? false : true);
12.559 + if (!msg->AddBool(strField, value))
12.560 + {
12.561 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.562 + }
12.563 +
12.564 + return 1;
12.565 +}
12.566 +
12.567 +static cell_t smn_PbAddString(IPluginContext *pCtx, const cell_t *params)
12.568 +{
12.569 + GET_MSG_FROM_HANDLE_OR_ERR();
12.570 + GET_FIELD_NAME_OR_ERR();
12.571 +
12.572 + char *strValue;
12.573 + if ((err=pCtx->LocalToString(params[3], &strValue)) != SP_ERROR_NONE)
12.574 + {
12.575 + pCtx->ThrowNativeErrorEx(err, NULL);
12.576 + return 0;
12.577 + }
12.578 +
12.579 + if (!msg->AddString(strField, strValue))
12.580 + {
12.581 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.582 + }
12.583 +
12.584 + return 1;
12.585 +}
12.586 +
12.587 +static cell_t smn_PbAddColor(IPluginContext *pCtx, const cell_t *params)
12.588 +{
12.589 + GET_MSG_FROM_HANDLE_OR_ERR();
12.590 + GET_FIELD_NAME_OR_ERR();
12.591 +
12.592 + cell_t *clrParams;
12.593 + if ((err=pCtx->LocalToPhysAddr(params[3], &clrParams)) != SP_ERROR_NONE)
12.594 + {
12.595 + pCtx->ThrowNativeErrorEx(err, NULL);
12.596 + return 0;
12.597 + }
12.598 +
12.599 + Color clr(
12.600 + clrParams[0],
12.601 + clrParams[1],
12.602 + clrParams[2],
12.603 + clrParams[3]);
12.604 +
12.605 + if (!msg->AddColor(strField, clr))
12.606 + {
12.607 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.608 + }
12.609 +
12.610 + return 1;
12.611 +}
12.612 +
12.613 +static cell_t smn_PbAddAngle(IPluginContext *pCtx, const cell_t *params)
12.614 +{
12.615 + GET_MSG_FROM_HANDLE_OR_ERR();
12.616 + GET_FIELD_NAME_OR_ERR();
12.617 +
12.618 + cell_t *angParams;
12.619 + if ((err=pCtx->LocalToPhysAddr(params[3], &angParams)) != SP_ERROR_NONE)
12.620 + {
12.621 + pCtx->ThrowNativeErrorEx(err, NULL);
12.622 + return 0;
12.623 + }
12.624 +
12.625 + QAngle ang(
12.626 + sp_ctof(angParams[0]),
12.627 + sp_ctof(angParams[1]),
12.628 + sp_ctof(angParams[2]));
12.629 +
12.630 + if (!msg->AddQAngle(strField, ang))
12.631 + {
12.632 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.633 + }
12.634 +
12.635 + return 1;
12.636 +}
12.637 +
12.638 +static cell_t smn_PbAddVector(IPluginContext *pCtx, const cell_t *params)
12.639 +{
12.640 + GET_MSG_FROM_HANDLE_OR_ERR();
12.641 + GET_FIELD_NAME_OR_ERR();
12.642 +
12.643 + cell_t *vecParams;
12.644 + if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
12.645 + {
12.646 + pCtx->ThrowNativeErrorEx(err, NULL);
12.647 + return 0;
12.648 + }
12.649 +
12.650 + Vector vec(
12.651 + sp_ctof(vecParams[0]),
12.652 + sp_ctof(vecParams[1]),
12.653 + sp_ctof(vecParams[2]));
12.654 +
12.655 + if (!msg->AddVector(strField, vec))
12.656 + {
12.657 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.658 + }
12.659 +
12.660 + return 1;
12.661 +}
12.662 +
12.663 +static cell_t smn_PbAddVector2D(IPluginContext *pCtx, const cell_t *params)
12.664 +{
12.665 + GET_MSG_FROM_HANDLE_OR_ERR();
12.666 + GET_FIELD_NAME_OR_ERR();
12.667 +
12.668 + cell_t *vecParams;
12.669 + if ((err=pCtx->LocalToPhysAddr(params[3], &vecParams)) != SP_ERROR_NONE)
12.670 + {
12.671 + pCtx->ThrowNativeErrorEx(err, NULL);
12.672 + return 0;
12.673 + }
12.674 +
12.675 + Vector2D vec(
12.676 + sp_ctof(vecParams[0]),
12.677 + sp_ctof(vecParams[1]));
12.678 +
12.679 + if (!msg->AddVector2D(strField, vec))
12.680 + {
12.681 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.682 + }
12.683 +
12.684 + return 1;
12.685 +}
12.686 +
12.687 +static cell_t smn_PbReadMessage(IPluginContext *pCtx, const cell_t *params)
12.688 +{
12.689 + GET_MSG_FROM_HANDLE_OR_ERR();
12.690 + GET_FIELD_NAME_OR_ERR();
12.691 +
12.692 + protobuf::Message *innerMsg;
12.693 + if (!msg->GetMessage(strField, &innerMsg))
12.694 + {
12.695 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.696 + }
12.697 +
12.698 + Handle_t outHndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
12.699 + msg->AddChildHandle(outHndl);
12.700 +
12.701 + return outHndl;
12.702 +}
12.703 +
12.704 +static cell_t smn_PbReadRepeatedMessage(IPluginContext *pCtx, const cell_t *params)
12.705 +{
12.706 + GET_MSG_FROM_HANDLE_OR_ERR();
12.707 + GET_FIELD_NAME_OR_ERR();
12.708 +
12.709 + const protobuf::Message *innerMsg;
12.710 + if (!msg->GetRepeatedMessage(strField, params[3], &innerMsg))
12.711 + {
12.712 + return pCtx->ThrowNativeError("Invalid field \"%s\"[%d] for message \"%s\"", strField, params[3], msg->GetProtobufMessage()->GetTypeName());
12.713 + }
12.714 +
12.715 + Handle_t outHndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(const_cast<protobuf::Message *>(innerMsg)), NULL, g_pCoreIdent, NULL);
12.716 + msg->AddChildHandle(outHndl);
12.717 +
12.718 + return outHndl;
12.719 +}
12.720 +
12.721 +static cell_t smn_PbAddMessage(IPluginContext *pCtx, const cell_t *params)
12.722 +{
12.723 + GET_MSG_FROM_HANDLE_OR_ERR();
12.724 + GET_FIELD_NAME_OR_ERR();
12.725 +
12.726 + protobuf::Message *innerMsg;
12.727 + if (!msg->AddMessage(strField, &innerMsg))
12.728 + {
12.729 + return pCtx->ThrowNativeError("Invalid field \"%s\" for message \"%s\"", strField, msg->GetProtobufMessage()->GetTypeName());
12.730 + }
12.731 +
12.732 + Handle_t outHndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(innerMsg), NULL, g_pCoreIdent, NULL);
12.733 + msg->AddChildHandle(outHndl);
12.734 +
12.735 + return outHndl;
12.736 +}
12.737 +
12.738 +REGISTER_NATIVES(protobufnatives)
12.739 +{
12.740 + {"PbReadInt", smn_PbReadInt},
12.741 + {"PbReadFloat", smn_PbReadFloat},
12.742 + {"PbReadBool", smn_PbReadBool},
12.743 + {"PbReadString", smn_PbReadString},
12.744 + {"PbReadColor", smn_PbReadColor},
12.745 + {"PbReadAngle", smn_PbReadAngle},
12.746 + {"PbReadVector", smn_PbReadVector},
12.747 + {"PbReadVector2D", smn_PbReadVector2D},
12.748 + {"PbGetRepeatedFieldCount", smn_PbGetRepeatedFieldCount},
12.749 + {"PbReadRepeatedInt", smn_PbReadRepeatedInt},
12.750 + {"PbReadRepeatedFloat", smn_PbReadRepeatedFloat},
12.751 + {"PbReadRepeatedBool", smn_PbReadRepeatedBool},
12.752 + {"PbReadRepeatedString", smn_PbReadRepeatedString},
12.753 + {"PbReadRepeatedColor", smn_PbReadRepeatedColor},
12.754 + {"PbReadRepeatedAngle", smn_PbReadRepeatedAngle},
12.755 + {"PbReadRepeatedVector", smn_PbReadRepeatedVector},
12.756 + {"PbReadRepeatedVector2D", smn_PbReadRepeatedVector2D},
12.757 + {"PbSetInt", smn_PbSetInt},
12.758 + {"PbSetFloat", smn_PbSetFloat},
12.759 + {"PbSetBool", smn_PbSetBool},
12.760 + {"PbSetString", smn_PbSetString},
12.761 + {"PbSetColor", smn_PbSetColor},
12.762 + {"PbSetAngle", smn_PbSetAngle},
12.763 + {"PbSetVector", smn_PbSetVector},
12.764 + {"PbSetVector2D", smn_PbSetVector2D},
12.765 + {"PbAddInt", smn_PbAddInt},
12.766 + {"PbAddFloat", smn_PbAddFloat},
12.767 + {"PbAddBool", smn_PbAddBool},
12.768 + {"PbAddString", smn_PbAddString},
12.769 + {"PbAddColor", smn_PbAddColor},
12.770 + {"PbAddAngle", smn_PbAddAngle},
12.771 + {"PbAddVector", smn_PbAddVector},
12.772 + {"PbAddVector2D", smn_PbAddVector2D},
12.773 + {"PbReadMessage", smn_PbReadMessage},
12.774 + {"PbReadRepeatedMessage", smn_PbReadRepeatedMessage},
12.775 + {"PbAddMessage", smn_PbAddMessage},
12.776 + {NULL, NULL}
12.777 +};
12.778 +
12.779 +/*
12.780 + @@@@@@@@@@@@@
12.781 + @@@@@@@@@@@@@@@@@@
12.782 + @@@@@@@@@@@@@@@@@@@@@
12.783 + @@@@@@@@@@@@@@@@@@@@@@@@
12.784 + @@@@@@@@ @@@@@@@@@@@@@
12.785 + @@@@@@@@ @@@@@@@@@@@@@
12.786 + @@@@@@ @@@@@@@@@@@@@@@
12.787 + 0000 @@@@@@@@@@@@@@@@@@@@@
12.788 + 000000000 @@@@@@@@@@@@@@@@@@@
12.789 + 0000000000000000000 @@@@@@@@@@@@@@@
12.790 + 00000000000000000000 @@@@@@@@@@@@@@@
12.791 + 000000000 @@@@@@@@@@@@@@@
12.792 + @@@@@@@@@@@@@@@@@
12.793 + @@@@@@@@@@@@@@@@@@
12.794 + @@@@@@@@@@@@@@@@@@
12.795 + @@@@@@@@@@@@@@@@@@ @@@@
12.796 + @@@@@@@@@@@@@@@@@@@ @@@@@@@
12.797 + @@@ @@@@ @@@ @@@@@@@@@@
12.798 + @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@ @@@@@
12.799 + @@@@@@@@@@@@@@@@@@@@@@@@@@ @@@ @@@@@@@@ @@ @@@@@@@@@@@@@@@
12.800 + @@@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@@@@@@@@
12.801 + @@@@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@ @@ @@@@@@@@@@@@@
12.802 + @@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@ @@@ @@@@@@@@@@@@
12.803 + @@@@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@ @@@@@@@@@@@
12.804 + @@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@ @@@@@ @@@@@@
12.805 + @@@@@@@@@ @@@@@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@ @@ @@@@@ @@@@@@@@
12.806 + @@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@ @@@@@@ @@@@ @@@@@@
12.807 + @@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@ @@@@@@
12.808 + @@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@@@ @@@@
12.809 + @@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@ @ @@@@@
12.810 + @@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@ @@@@ ////
12.811 + //////////// @@@@@@@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@@@ @@ @@@@@@@@@ @@@@ //// ////////////
12.812 + ///////////////// /// @@@@@ @@@@ @@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@@ ///// /////// /////////
12.813 + ///////////////////// ///// @@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@ @@@@@@@ @ @@@@ ////// /////// ///////////////
12.814 + ///////////////////////// /////// @@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@@ @@@@ ////// //////// ////////////////////
12.815 + //////////////////////////// ////////// @@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@ @@@ ////// ////////// ////////////////////////
12.816 +//////////////////// ////////// /////////// @@@@@@@@@@@@@@@@@ @@@@@@@@ @@@ @@@@@@ ////// //////////// //////////////////////////
12.817 +//////////////////// //////////// /////////// @@@@@@@@@@@@@@@@ @@@@ ///////////////////// /////////////////////////////
12.818 +///////////////////// ////////////// ////// @@@@@@@@@ ///////////////////////////////////////////////////////////
12.819 + //////////////////// ///////////////////////////////////// ///////////////////////////////////////////////////////////////////////
12.820 + ///////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////
12.821 + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
12.822 + //////////////////////////////////////////////////////////////////////////////////////////////////////////////
12.823 + /////////////////////////////////////////////////////////////////////////////////////////
12.824 + //////////////////////////////////////////////////////////
12.825 +*/
12.826 +#endif // USE_PROTOBUF_USERMESSAGES
13.1 --- a/core/smn_usermsgs.cpp Mon Jan 07 09:09:14 2013 -0500
13.2 +++ b/core/smn_usermsgs.cpp Tue Jan 22 21:43:12 2013 -0500
13.3 @@ -31,15 +31,22 @@
13.4
13.5 #include "HandleSys.h"
13.6 #include "PluginSys.h"
13.7 -#include "UserMessages.h"
13.8 #include "PlayerManager.h"
13.9 #include "smn_usermsgs.h"
13.10 +#ifdef USE_PROTOBUF_USERMESSAGES
13.11 +#include "UserMessagePBHelpers.h"
13.12 +#endif
13.13
13.14 -HandleType_t g_WrBitBufType;
13.15 -HandleType_t g_RdBitBufType;
13.16 +HandleType_t g_ProtobufType = NO_HANDLE_TYPE;
13.17 +HandleType_t g_WrBitBufType = NO_HANDLE_TYPE;
13.18 +HandleType_t g_RdBitBufType = NO_HANDLE_TYPE;
13.19 +
13.20 Handle_t g_CurMsgHandle;
13.21 +
13.22 +#ifndef USE_PROTOBUF_USERMESSAGES
13.23 Handle_t g_ReadBufHandle;
13.24 bf_read g_ReadBitBuf;
13.25 +#endif
13.26
13.27 int g_MsgPlayers[256];
13.28 bool g_IsMsgInExec = false;
13.29 @@ -85,10 +92,14 @@
13.30 g_HandleSys.InitAccessDefaults(NULL, &sec);
13.31 sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY;
13.32
13.33 +#ifdef USE_PROTOBUF_USERMESSAGES
13.34 + g_ProtobufType = g_HandleSys.CreateType("ProtobufUM", this, 0, NULL, NULL, g_pCoreIdent, NULL);
13.35 +#else
13.36 g_WrBitBufType = g_HandleSys.CreateType("BitBufWriter", this, 0, NULL, NULL, g_pCoreIdent, NULL);
13.37 g_RdBitBufType = g_HandleSys.CreateType("BitBufReader", this, 0, NULL, &sec, g_pCoreIdent, NULL);
13.38
13.39 g_ReadBufHandle = g_HandleSys.CreateHandle(g_RdBitBufType, &g_ReadBitBuf, NULL, g_pCoreIdent, NULL);
13.40 +#endif
13.41
13.42 g_PluginSys.AddPluginsListener(this);
13.43 }
13.44 @@ -98,6 +109,11 @@
13.45 HandleSecurity sec;
13.46 sec.pIdentity = g_pCoreIdent;
13.47
13.48 +#ifdef USE_PROTOBUF_USERMESSAGES
13.49 + g_HandleSys.RemoveType(g_ProtobufType, g_pCoreIdent);
13.50 +
13.51 + g_ProtobufType = 0;
13.52 +#else
13.53 g_HandleSys.FreeHandle(g_ReadBufHandle, &sec);
13.54
13.55 g_HandleSys.RemoveType(g_WrBitBufType, g_pCoreIdent);
13.56 @@ -105,15 +121,24 @@
13.57
13.58 g_WrBitBufType = 0;
13.59 g_RdBitBufType = 0;
13.60 +#endif
13.61 }
13.62
13.63 void UsrMessageNatives::OnHandleDestroy(HandleType_t type, void *object)
13.64 {
13.65 +#ifdef USE_PROTOBUF_USERMESSAGES
13.66 + delete (SMProtobufMessage *)object;
13.67 +#endif
13.68 }
13.69
13.70 bool UsrMessageNatives::GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
13.71 {
13.72 +#ifdef USE_PROTOBUF_USERMESSAGES
13.73 + // Different messages have different sizes, but this works as an approximate
13.74 + *pSize = sizeof(protobuf::Message) + sizeof(SMProtobufMessage);
13.75 +#else
13.76 *pSize = sizeof(bf_read);
13.77 +#endif
13.78
13.79 return true;
13.80 }
13.81 @@ -275,37 +300,69 @@
13.82 return m_Notify;
13.83 }
13.84
13.85 +#ifdef USE_PROTOBUF_USERMESSAGES
13.86 +void MsgListenerWrapper::OnUserMessage(int msg_id, protobuf::Message *msg, IRecipientFilter *pFilter)
13.87 +#else
13.88 void MsgListenerWrapper::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
13.89 +#endif
13.90 {
13.91 cell_t res;
13.92 + Handle_t hndl;
13.93 size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
13.94
13.95 +#ifdef USE_PROTOBUF_USERMESSAGES
13.96 + hndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), NULL, g_pCoreIdent, NULL);
13.97 +#else
13.98 g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten());
13.99 + hndl = g_ReadBufHandle;
13.100 +#endif
13.101
13.102 m_Hook->PushCell(msg_id);
13.103 - m_Hook->PushCell(g_ReadBufHandle);
13.104 + m_Hook->PushCell(hndl);
13.105 m_Hook->PushArray(g_MsgPlayers, size);
13.106 m_Hook->PushCell(size);
13.107 m_Hook->PushCell(pFilter->IsReliable());
13.108 m_Hook->PushCell(pFilter->IsInitMessage());
13.109 m_Hook->Execute(&res);
13.110 +
13.111 +#ifdef USE_PROTOBUF_USERMESSAGES
13.112 + HandleSecurity sec;
13.113 + sec.pIdentity = g_pCoreIdent;
13.114 + g_HandleSys.FreeHandle(hndl, &sec);
13.115 +#endif
13.116 }
13.117
13.118 +#ifdef USE_PROTOBUF_USERMESSAGES
13.119 +ResultType MsgListenerWrapper::InterceptUserMessage(int msg_id, protobuf::Message *msg, IRecipientFilter *pFilter)
13.120 +#else
13.121 ResultType MsgListenerWrapper::InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
13.122 +#endif
13.123 {
13.124 + Handle_t hndl;
13.125 cell_t res = static_cast<cell_t>(Pl_Continue);
13.126 size_t size = _FillInPlayers(g_MsgPlayers, pFilter);
13.127
13.128 +#ifdef USE_PROTOBUF_USERMESSAGES
13.129 + hndl = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), NULL, g_pCoreIdent, NULL);
13.130 +#else
13.131 g_ReadBitBuf.StartReading(bf->GetBasePointer(), bf->GetNumBytesWritten());
13.132 + hndl = g_ReadBufHandle;
13.133 +#endif
13.134
13.135 m_Intercept->PushCell(msg_id);
13.136 - m_Intercept->PushCell(g_ReadBufHandle);
13.137 + m_Intercept->PushCell(hndl);
13.138 m_Intercept->PushArray(g_MsgPlayers, size);
13.139 m_Intercept->PushCell(size);
13.140 m_Intercept->PushCell(pFilter->IsReliable());
13.141 m_Intercept->PushCell(pFilter->IsInitMessage());
13.142 m_Intercept->Execute(&res);
13.143
13.144 +#ifdef USE_PROTOBUF_USERMESSAGES
13.145 + HandleSecurity sec;
13.146 + sec.pIdentity = g_pCoreIdent;
13.147 + g_HandleSys.FreeHandle(hndl, &sec);
13.148 +#endif
13.149 +
13.150 return static_cast<ResultType>(res);
13.151 }
13.152
13.153 @@ -330,6 +387,11 @@
13.154
13.155 static UsrMessageNatives s_UsrMessageNatives;
13.156
13.157 +static cell_t smn_GetUserMessageType(IPluginContext *pCtx, const cell_t *params)
13.158 +{
13.159 + return g_UserMsgs.GetUserMessageType();
13.160 +}
13.161 +
13.162 static cell_t smn_GetUserMessageId(IPluginContext *pCtx, const cell_t *params)
13.163 {
13.164 char *msgname;
13.165 @@ -353,7 +415,6 @@
13.166 cell_t *cl_array;
13.167 unsigned int numClients;
13.168 int msgid;
13.169 - bf_write *pBitBuf;
13.170 int client;
13.171 CPlayer *pPlayer = NULL;
13.172
13.173 @@ -387,13 +448,24 @@
13.174 }
13.175 }
13.176
13.177 - pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, numClients, params[4]);
13.178 +#ifdef USE_PROTOBUF_USERMESSAGES
13.179 + protobuf::Message *msg = g_UserMsgs.StartProtobufMessage(msgid, cl_array, numClients, params[4]);
13.180 + if (!msg)
13.181 + {
13.182 + return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
13.183 + }
13.184 +
13.185 + g_CurMsgHandle = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), pCtx->GetIdentity(), g_pCoreIdent, NULL);
13.186 +#else
13.187 + bf_write *pBitBuf = g_UserMsgs.StartBitBufMessage(msgid, cl_array, numClients, params[4]);
13.188 if (!pBitBuf)
13.189 {
13.190 return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
13.191 }
13.192
13.193 g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
13.194 +#endif
13.195 +
13.196 g_IsMsgInExec = true;
13.197
13.198 return g_CurMsgHandle;
13.199 @@ -403,7 +475,6 @@
13.200 {
13.201 cell_t *cl_array;
13.202 unsigned int numClients;
13.203 - bf_write *pBitBuf;
13.204 int client;
13.205 CPlayer *pPlayer = NULL;
13.206 int msgid = params[1];
13.207 @@ -436,13 +507,23 @@
13.208 }
13.209 }
13.210
13.211 - pBitBuf = g_UserMsgs.StartMessage(msgid, cl_array, numClients, params[4]);
13.212 +#ifdef USE_PROTOBUF_USERMESSAGES
13.213 + protobuf::Message *msg = g_UserMsgs.StartProtobufMessage(msgid, cl_array, numClients, params[4]);
13.214 + if (!msg)
13.215 + {
13.216 + return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
13.217 + }
13.218 +
13.219 + g_CurMsgHandle = g_HandleSys.CreateHandle(g_ProtobufType, new SMProtobufMessage(msg), pCtx->GetIdentity(), g_pCoreIdent, NULL);
13.220 +#else
13.221 + bf_write *pBitBuf = g_UserMsgs.StartBitBufMessage(msgid, cl_array, numClients, params[4]);
13.222 if (!pBitBuf)
13.223 {
13.224 return pCtx->ThrowNativeError("Unable to execute a new message while in hook");
13.225 }
13.226
13.227 g_CurMsgHandle = g_HandleSys.CreateHandle(g_WrBitBufType, pBitBuf, pCtx->GetIdentity(), g_pCoreIdent, NULL);
13.228 +#endif
13.229 g_IsMsgInExec = true;
13.230
13.231 return g_CurMsgHandle;
13.232 @@ -534,6 +615,7 @@
13.233
13.234 REGISTER_NATIVES(usrmsgnatives)
13.235 {
13.236 + {"GetUserMessageType", smn_GetUserMessageType},
13.237 {"GetUserMessageId", smn_GetUserMessageId},
13.238 {"GetUserMessageName", smn_GetUserMessageName},
13.239 {"StartMessage", smn_StartMessage},
14.1 --- a/core/smn_usermsgs.h Mon Jan 07 09:09:14 2013 -0500
14.2 +++ b/core/smn_usermsgs.h Tue Jan 22 21:43:12 2013 -0500
14.3 @@ -32,9 +32,14 @@
14.4 #ifndef _INCLUDE_SOURCEMOD_CMSGLISTENERWRAPPER_H_
14.5 #define _INCLUDE_SOURCEMOD_CMSGLISTENERWRAPPER_H_
14.6
14.7 -extern int g_MsgPlayers[256];
14.8 +#include "UserMessages.h"
14.9
14.10 -class MsgListenerWrapper : public IUserMessageListener
14.11 +class MsgListenerWrapper
14.12 +#ifdef USE_PROTOBUF_USERMESSAGES
14.13 + : public IProtobufUserMessageListener
14.14 +#else
14.15 + : public IBitBufUserMessageListener
14.16 +#endif
14.17 {
14.18 public:
14.19 void Initialize(int msgid, IPluginFunction *hook, IPluginFunction *notify, bool intercept);
14.20 @@ -43,8 +48,13 @@
14.21 IPluginFunction *GetHookedFunction() const;
14.22 IPluginFunction *GetNotifyFunction() const;
14.23 public: //IUserMessageListener
14.24 +#ifdef USE_PROTOBUF_USERMESSAGES
14.25 + void OnUserMessage(int msg_id, protobuf::Message *msg, IRecipientFilter *pFilter);
14.26 + ResultType InterceptUserMessage(int msg_id, protobuf::Message *msg, IRecipientFilter *pFilter);
14.27 +#else
14.28 void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
14.29 ResultType InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter);
14.30 +#endif
14.31 void OnPostUserMessage(int msg_id, bool sent);
14.32 private:
14.33 size_t _FillInPlayers(int *pl_array, IRecipientFilter *pFilter);
14.34 @@ -56,4 +66,8 @@
14.35 int m_MsgId;
14.36 };
14.37
14.38 +extern HandleType_t g_WrBitBufType;
14.39 +extern HandleType_t g_RdBitBufType;
14.40 +extern HandleType_t g_ProtobufType;
14.41 +
14.42 #endif //_INCLUDE_SOURCEMOD_CMSGLISTENERWRAPPER_H_
15.1 --- a/core/sourcemod.h Mon Jan 07 09:09:14 2013 -0500
15.2 +++ b/core/sourcemod.h Tue Jan 22 21:43:12 2013 -0500
15.3 @@ -152,7 +152,5 @@
15.4 extern bool g_Loaded;
15.5 extern bool sm_show_debug_spew;
15.6 extern SourceModBase g_SourceMod;
15.7 -extern HandleType_t g_WrBitBufType; //:TODO: find a better place for this
15.8 -extern HandleType_t g_RdBitBufType; //:TODO: find a better place for this
15.9
15.10 #endif //_INCLUDE_SOURCEMOD_GLOBALHEADER_H_
16.1 --- a/plugins/funcommands/blind.sp Mon Jan 07 09:09:14 2013 -0500
16.2 +++ b/plugins/funcommands/blind.sp Tue Jan 22 21:43:12 2013 -0500
16.3 @@ -38,23 +38,39 @@
16.4 new targets[2];
16.5 targets[0] = target;
16.6
16.7 - new Handle:message = StartMessageEx(g_FadeUserMsgId, targets, 1);
16.8 - BfWriteShort(message, 1536);
16.9 - BfWriteShort(message, 1536);
16.10 -
16.11 + new duration = 1536;
16.12 + new holdtime = 1536;
16.13 + new flags;
16.14 if (amount == 0)
16.15 {
16.16 - BfWriteShort(message, (0x0001 | 0x0010));
16.17 + flags = (0x0001 | 0x0010);
16.18 }
16.19 else
16.20 {
16.21 - BfWriteShort(message, (0x0002 | 0x0008));
16.22 + flags = (0x0002 | 0x0008);
16.23 }
16.24
16.25 - BfWriteByte(message, 0);
16.26 - BfWriteByte(message, 0);
16.27 - BfWriteByte(message, 0);
16.28 - BfWriteByte(message, amount);
16.29 + new color[4] = { 0, 0, 0, 0 };
16.30 + color[3] = amount;
16.31 +
16.32 + new Handle:message = StartMessageEx(g_FadeUserMsgId, targets, 1);
16.33 + if (GetUserMessageType() == UM_Protobuf)
16.34 + {
16.35 + PbSetInt(message, "duration", duration);
16.36 + PbSetInt(message, "hold_time", holdtime);
16.37 + PbSetInt(message, "flags", flags);
16.38 + PbSetColor(message, "clr", color);
16.39 + }
16.40 + else
16.41 + {
16.42 + BfWriteShort(message, duration);
16.43 + BfWriteShort(message, holdtime);
16.44 + BfWriteShort(message, flags);
16.45 + BfWriteByte(message, color[0]);
16.46 + BfWriteByte(message, color[1]);
16.47 + BfWriteByte(message, color[2]);
16.48 + BfWriteByte(message, color[3]);
16.49 + }
16.50
16.51 EndMessage();
16.52
17.1 --- a/plugins/funcommands/drug.sp Mon Jan 07 09:09:14 2013 -0500
17.2 +++ b/plugins/funcommands/drug.sp Tue Jan 22 21:43:12 2013 -0500
17.3 @@ -51,17 +51,34 @@
17.4 TeleportEntity(client, NULL_VECTOR, angs, NULL_VECTOR);
17.5
17.6 new clients[2];
17.7 - clients[0] = client;
17.8 -
17.9 + clients[0] = client;
17.10 +
17.11 + new duration = 1536;
17.12 + new holdtime = 1536;
17.13 + new flags = (0x0001 | 0x0010);
17.14 + new color[4] = { 0, 0, 0, 0 };
17.15 +
17.16 new Handle:message = StartMessageEx(g_FadeUserMsgId, clients, 1);
17.17 - BfWriteShort(message, 1536);
17.18 - BfWriteShort(message, 1536);
17.19 - BfWriteShort(message, (0x0001 | 0x0010));
17.20 - BfWriteByte(message, 0);
17.21 - BfWriteByte(message, 0);
17.22 - BfWriteByte(message, 0);
17.23 - BfWriteByte(message, 0);
17.24 - EndMessage();
17.25 +
17.26 + if (GetUserMessageType() == UM_Protobuf)
17.27 + {
17.28 + PbSetInt(message, "duration", duration);
17.29 + PbSetInt(message, "hold_time", holdtime);
17.30 + PbSetInt(message, "flags", flags);
17.31 + PbSetColor(message, "clr", color);
17.32 + }
17.33 + else
17.34 + {
17.35 + BfWriteShort(message, duration);
17.36 + BfWriteShort(message, holdtime);
17.37 + BfWriteShort(message, flags);
17.38 + BfWriteByte(message, color[0]);
17.39 + BfWriteByte(message, color[1]);
17.40 + BfWriteByte(message, color[2]);
17.41 + BfWriteByte(message, color[3]);
17.42 + }
17.43 +
17.44 + EndMessage();
17.45 }
17.46
17.47 KillDrugTimer(client)
17.48 @@ -152,16 +169,35 @@
17.49 new clients[2];
17.50 clients[0] = client;
17.51
17.52 + new duration = 255;
17.53 + new holdtime = 255;
17.54 + new flags = 0x0002;
17.55 + new color[4] = { 0, 0, 0, 128 };
17.56 + color[0] = GetRandomInt(0,255);
17.57 + color[1] = GetRandomInt(0,255);
17.58 + color[2] = GetRandomInt(0,255);
17.59 +
17.60 new Handle:message = StartMessageEx(g_FadeUserMsgId, clients, 1);
17.61 - BfWriteShort(message, 255);
17.62 - BfWriteShort(message, 255);
17.63 - BfWriteShort(message, (0x0002));
17.64 - BfWriteByte(message, GetRandomInt(0,255));
17.65 - BfWriteByte(message, GetRandomInt(0,255));
17.66 - BfWriteByte(message, GetRandomInt(0,255));
17.67 - BfWriteByte(message, 128);
17.68
17.69 - EndMessage();
17.70 + if (GetUserMessageType() == UM_Protobuf)
17.71 + {
17.72 + PbSetInt(message, "duration", duration);
17.73 + PbSetInt(message, "hold_time", holdtime);
17.74 + PbSetInt(message, "flags", flags);
17.75 + PbSetColor(message, "clr", color);
17.76 + }
17.77 + else
17.78 + {
17.79 + BfWriteShort(message, duration);
17.80 + BfWriteShort(message, holdtime);
17.81 + BfWriteShort(message, flags);
17.82 + BfWriteByte(message, color[0]);
17.83 + BfWriteByte(message, color[1]);
17.84 + BfWriteByte(message, color[2]);
17.85 + BfWriteByte(message, color[3]);
17.86 + }
17.87 +
17.88 + EndMessage();
17.89
17.90 return Plugin_Handled;
17.91 }
18.1 --- a/plugins/include/core.inc Mon Jan 07 09:09:14 2013 -0500
18.2 +++ b/plugins/include/core.inc Tue Jan 22 21:43:12 2013 -0500
18.3 @@ -167,6 +167,67 @@
18.4 MarkNativeAsOptional("RequireFeature");
18.5 MarkNativeAsOptional("AddCommandListener");
18.6 MarkNativeAsOptional("RemoveCommandListener");
18.7 +
18.8 + MarkNativeAsOptional("BfWriteBool");
18.9 + MarkNativeAsOptional("BfWriteByte");
18.10 + MarkNativeAsOptional("BfWriteChar");
18.11 + MarkNativeAsOptional("BfWriteShort");
18.12 + MarkNativeAsOptional("BfWriteWord");
18.13 + MarkNativeAsOptional("BfWriteNum");
18.14 + MarkNativeAsOptional("BfWriteFloat");
18.15 + MarkNativeAsOptional("BfWriteString");
18.16 + MarkNativeAsOptional("BfWriteEntity");
18.17 + MarkNativeAsOptional("BfWriteAngle");
18.18 + MarkNativeAsOptional("BfWriteCoord");
18.19 + MarkNativeAsOptional("BfWriteVecCoord");
18.20 + MarkNativeAsOptional("BfWriteVecNormal");
18.21 + MarkNativeAsOptional("BfWriteAngles");
18.22 + MarkNativeAsOptional("BfReadBool");
18.23 + MarkNativeAsOptional("BfReadByte");
18.24 + MarkNativeAsOptional("BfReadChar");
18.25 + MarkNativeAsOptional("BfReadShort");
18.26 + MarkNativeAsOptional("BfReadWord");
18.27 + MarkNativeAsOptional("BfReadNum");
18.28 + MarkNativeAsOptional("BfReadFloat");
18.29 + MarkNativeAsOptional("BfReadString");
18.30 + MarkNativeAsOptional("BfReadEntity");
18.31 + MarkNativeAsOptional("BfReadAngle");
18.32 + MarkNativeAsOptional("BfReadCoord");
18.33 + MarkNativeAsOptional("BfReadVecCoord");
18.34 + MarkNativeAsOptional("BfReadVecNormal");
18.35 + MarkNativeAsOptional("BfReadAngles");
18.36 + MarkNativeAsOptional("BfGetNumBytesLeft");
18.37 +
18.38 + MarkNativeAsOptional("PbReadInt");
18.39 + MarkNativeAsOptional("PbReadFloat");
18.40 + MarkNativeAsOptional("PbReadString");
18.41 + MarkNativeAsOptional("PbReadColor");
18.42 + MarkNativeAsOptional("PbReadAngle");
18.43 + MarkNativeAsOptional("PbReadVector");
18.44 + MarkNativeAsOptional("PbReadVector2D");
18.45 + MarkNativeAsOptional("PbGetRepeatedFieldCount");
18.46 + MarkNativeAsOptional("PbReadRepeatedInt");
18.47 + MarkNativeAsOptional("PbReadRepeatedFloat");
18.48 + MarkNativeAsOptional("PbReadRepeatedString");
18.49 + MarkNativeAsOptional("PbReadRepeatedColor");
18.50 + MarkNativeAsOptional("PbReadRepeatedAngle");
18.51 + MarkNativeAsOptional("PbReadRepeatedVector");
18.52 + MarkNativeAsOptional("PbReadRepeatedVector2D");
18.53 + MarkNativeAsOptional("PbSetInt");
18.54 + MarkNativeAsOptional("PbSetFloat");
18.55 + MarkNativeAsOptional("PbSetString");
18.56 + MarkNativeAsOptional("PbSetColor");
18.57 + MarkNativeAsOptional("PbSetAngle");
18.58 + MarkNativeAsOptional("PbSetVector");
18.59 + MarkNativeAsOptional("PbSetVector2D");
18.60 + MarkNativeAsOptional("PbAddInt");
18.61 + MarkNativeAsOptional("PbAddFloat");
18.62 + MarkNativeAsOptional("PbAddString");
18.63 + MarkNativeAsOptional("PbAddColor");
18.64 + MarkNativeAsOptional("PbAddAngle");
18.65 + MarkNativeAsOptional("PbAddVector");
18.66 + MarkNativeAsOptional("PbAddVector2D");
18.67 +
18.68 VerifyCoreVersion();
18.69 }
18.70
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/plugins/include/protobuf.inc Tue Jan 22 21:43:12 2013 -0500
19.3 @@ -0,0 +1,433 @@
19.4 +/**
19.5 + * vim: set ts=4 :
19.6 + * =============================================================================
19.7 + * SourceMod (C)2013 AlliedModders LLC. All rights reserved.
19.8 + * =============================================================================
19.9 + *
19.10 + * This file is part of the SourceMod/SourcePawn SDK.
19.11 + *
19.12 + * This program is free software; you can redistribute it and/or modify it under
19.13 + * the terms of the GNU General Public License, version 3.0, as published by the
19.14 + * Free Software Foundation.
19.15 + *
19.16 + * This program is distributed in the hope that it will be useful, but WITHOUT
19.17 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19.18 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
19.19 + * details.
19.20 + *
19.21 + * You should have received a copy of the GNU General Public License along with
19.22 + * this program. If not, see <http://www.gnu.org/licenses/>.
19.23 + *
19.24 + * As a special exception, AlliedModders LLC gives you permission to link the
19.25 + * code of this program (as well as its derivative works) to "Half-Life 2," the
19.26 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
19.27 + * by the Valve Corporation. You must obey the GNU General Public License in
19.28 + * all respects for all other code used. Additionally, AlliedModders LLC grants
19.29 + * this exception to all derivative works. AlliedModders LLC defines further
19.30 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
19.31 + * or <http://www.sourcemod.net/license.php>.
19.32 + *
19.33 + * Version: $Id$
19.34 + */
19.35 +
19.36 +#if defined _protobuf_included
19.37 +#endinput
19.38 +#endif
19.39 +#define _protobuf_included
19.40 +
19.41 +/**
19.42 + * Reads an int32, uint32, sint32, fixed32, or sfixed32 from a protobuf message.
19.43 + *
19.44 + * @param pb protobuf handle.
19.45 + * @param field Field name.
19.46 + * @return Integer value read.
19.47 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.48 + */
19.49 +native PbReadInt(Handle:pb, const String:field[]);
19.50 +
19.51 +/**
19.52 + * Reads a float or downcasted double from a protobuf message.
19.53 + *
19.54 + * @param pb protobuf handle.
19.55 + * @param field Field name.
19.56 + * @return Float value read.
19.57 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.58 + */
19.59 +native Float:PbReadFloat(Handle:pb, const String:field[]);
19.60 +
19.61 +/**
19.62 + * Reads a bool from a protobuf message.
19.63 + *
19.64 + * @param pb protobuf handle.
19.65 + * @param field Field name.
19.66 + * @return Boolean value read.
19.67 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.68 + */
19.69 +native bool:PbReadBool(Handle:pb, const String:field[]);
19.70 +
19.71 +/**
19.72 + * Reads a string from a protobuf message.
19.73 + *
19.74 + * @param pb protobuf handle.
19.75 + * @param field Field name.
19.76 + * @param buffer Destination string buffer.
19.77 + * @param maxlength Maximum length of output string buffer.
19.78 + * @noreturn
19.79 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.80 + */
19.81 +native PbReadString(Handle:pb, const String:field[], String:buffer[], maxlength);
19.82 +
19.83 +/**
19.84 + * Reads an RGBA color value from a protobuf message.
19.85 + *
19.86 + * @param pb protobuf handle.
19.87 + * @param field Field name.
19.88 + * @param buffer Destination color buffer.
19.89 + * @noreturn
19.90 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.91 + */
19.92 +native PbReadColor(Handle:pb, const String:field[], buffer[4]);
19.93 +
19.94 +/**
19.95 + * Reads an XYZ angle value from a protobuf message.
19.96 + *
19.97 + * @param pb protobuf handle.
19.98 + * @param field Field name.
19.99 + * @param buffer Destination angle buffer.
19.100 + * @noreturn
19.101 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.102 + */
19.103 +native PbReadAngle(Handle:pb, const String:field[], Float:buffer[3]);
19.104 +
19.105 +/**
19.106 + * Reads an XYZ vector value from a protobuf message.
19.107 + *
19.108 + * @param pb protobuf handle.
19.109 + * @param field Field name.
19.110 + * @param buffer Destination vector buffer.
19.111 + * @noreturn
19.112 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.113 + */
19.114 +native PbReadVector(Handle:pb, const String:field[], Float:buffer[3]);
19.115 +
19.116 +/**
19.117 + * Reads an XY vector value from a protobuf message.
19.118 + *
19.119 + * @param pb protobuf handle.
19.120 + * @param field Field name.
19.121 + * @param buffer Destination vector buffer.
19.122 + * @noreturn
19.123 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.124 + */
19.125 +native PbReadVector2D(Handle:pb, const String:field[], Float:buffer[2]);
19.126 +
19.127 +/**
19.128 + * Gets the number of elements in a repeated field of a protobuf message.
19.129 + *
19.130 + * @param pb protobuf handle.
19.131 + * @param field Field name.
19.132 + * @return Number of elements in the field.
19.133 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.134 + */
19.135 +native PbGetRepeatedFieldCount(Handle:pb, const String:field[]);
19.136 +
19.137 +/**
19.138 + * Reads an int32, uint32, sint32, fixed32, or sfixed32 from a protobuf message repeated field.
19.139 + *
19.140 + * @param pb protobuf handle.
19.141 + * @param field Field name.
19.142 + * @param index Index in the repeated field.
19.143 + * @return Integer value read.
19.144 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.145 + */
19.146 +native PbReadRepeatedInt(Handle:pb, const String:field[], index);
19.147 +
19.148 +/**
19.149 + * Reads a float or downcasted double from a protobuf message repeated field.
19.150 + *
19.151 + * @param pb protobuf handle.
19.152 + * @param field Field name.
19.153 + * @param index Index in the repeated field.
19.154 + * @return Float value read.
19.155 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.156 + */
19.157 +native Float:PbReadRepeatedFloat(Handle:pb, const String:field[], index);
19.158 +
19.159 +/**
19.160 + * Reads a bool from a protobuf message repeated field.
19.161 + *
19.162 + * @param pb protobuf handle.
19.163 + * @param field Field name.
19.164 + * @param index Index in the repeated field.
19.165 + * @return Boolean value read.
19.166 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.167 + */
19.168 +native bool:PbReadRepeatedBool(Handle:pb, const String:field[], index);
19.169 +
19.170 +/**
19.171 + * Reads a string from a protobuf message repeated field.
19.172 + *
19.173 + * @param pb protobuf handle.
19.174 + * @param field Field name.
19.175 + * @param index Index in the repeated field.
19.176 + * @param buffer Destination string buffer.
19.177 + * @param maxlength Maximum length of output string buffer.
19.178 + * @noreturn
19.179 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.180 + */
19.181 +native PbReadRepeatedString(Handle:pb, const String:field[], index, String:buffer[], size);
19.182 +
19.183 +/**
19.184 + * Reads an RGBA color value from a protobuf message repeated field.
19.185 + *
19.186 + * @param pb protobuf handle.
19.187 + * @param field Field name.
19.188 + * @param index Index in the repeated field.
19.189 + * @param buffer Destination color buffer.
19.190 + * @noreturn
19.191 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.192 + */
19.193 +native PbReadRepeatedColor(Handle:pb, const String:field[], index, buffer[4]);
19.194 +
19.195 +/**
19.196 + * Reads an XYZ angle value from a protobuf message repeated field.
19.197 + *
19.198 + * @param pb protobuf handle.
19.199 + * @param field Field name.
19.200 + * @param index Index in the repeated field.
19.201 + * @param buffer Destination angle buffer.
19.202 + * @noreturn
19.203 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.204 + */
19.205 +native PbReadRepeatedAngle(Handle:pb, const String:field[], index, Float:buffer[3]);
19.206 +
19.207 +/**
19.208 + * Reads an XYZ vector value from a protobuf message repeated field.
19.209 + *
19.210 + * @param pb protobuf handle.
19.211 + * @param field Field name.
19.212 + * @param index Index in the repeated field.
19.213 + * @param buffer Destination vector buffer.
19.214 + * @noreturn
19.215 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.216 + */
19.217 +native PbReadRepeatedVector(Handle:pb, const String:field[], index, Float:buffer[3]);
19.218 +
19.219 +/**
19.220 + * Reads an XY vector value from a protobuf message repeated field.
19.221 + *
19.222 + * @param pb protobuf handle.
19.223 + * @param field Field name.
19.224 + * @param index Index in the repeated field.
19.225 + * @param buffer Destination vector buffer.
19.226 + * @noreturn
19.227 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.228 + */
19.229 +native PbReadRepeatedVector2D(Handle:pb, const String:field[], index, Float:buffer[2]);
19.230 +
19.231 +/**
19.232 + * Sets an int32, uint32, sint32, fixed32, or sfixed32 on a protobuf message.
19.233 + *
19.234 + * @param pb protobuf handle.
19.235 + * @param field Field name.
19.236 + * @param value Integer value to set.
19.237 + * @noreturn
19.238 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.239 + */
19.240 +native PbSetInt(Handle:pb, const String:field[], value);
19.241 +
19.242 +/**
19.243 + * Sets a float or double on a protobuf message.
19.244 + *
19.245 + * @param pb protobuf handle.
19.246 + * @param field Field name.
19.247 + * @param value Float value to set.
19.248 + * @noreturn
19.249 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.250 + */
19.251 +native PbSetFloat(Handle:pb, const String:field[], Float:value);
19.252 +
19.253 +/**
19.254 + * Sets a bool on a protobuf message.
19.255 + *
19.256 + * @param pb protobuf handle.
19.257 + * @param field Field name.
19.258 + * @param value Boolean value to set.
19.259 + * @noreturn
19.260 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.261 + */
19.262 +native PbSetBool(Handle:pb, const String:field[], bool:value);
19.263 +
19.264 +/**
19.265 + * Sets a string on a protobuf message.
19.266 + *
19.267 + * @param pb protobuf handle.
19.268 + * @param field Field name.
19.269 + * @param value String value to set.
19.270 + * @noreturn
19.271 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.272 + */
19.273 +native PbSetString(Handle:pb, const String:field[], const String:value[]);
19.274 +
19.275 +/**
19.276 + * Sets an RGBA color on a protobuf message.
19.277 + *
19.278 + * @param pb protobuf handle.
19.279 + * @param field Field name.
19.280 + * @param value Color value to set.
19.281 + * @noreturn
19.282 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.283 + */
19.284 +native PbSetColor(Handle:pb, const String:field[], const color[4]);
19.285 +
19.286 +/**
19.287 + * Sets an XYZ angle on a protobuf message.
19.288 + *
19.289 + * @param pb protobuf handle.
19.290 + * @param field Field name.
19.291 + * @param value Angle value to set.
19.292 + * @noreturn
19.293 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.294 + */
19.295 +native PbSetAngle(Handle:pb, const String:field[], const Float:angle[3]);
19.296 +
19.297 +/**
19.298 + * Sets an XYZ vector on a protobuf message.
19.299 + *
19.300 + * @param pb protobuf handle.
19.301 + * @param field Field name.
19.302 + * @param value Vector value to set.
19.303 + * @noreturn
19.304 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.305 + */
19.306 +native PbSetVector(Handle:pb, const String:field[], const Float:vec[3]);
19.307 +
19.308 +/**
19.309 + * Sets an XY vector on a protobuf message.
19.310 + *
19.311 + * @param pb protobuf handle.
19.312 + * @param field Field name.
19.313 + * @param value Vector value to set.
19.314 + * @noreturn
19.315 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.316 + */
19.317 +native PbSetVector2D(Handle:pb, const String:field[], const Float:vec[2]);
19.318 +
19.319 +/**
19.320 + * Add an int32, uint32, sint32, fixed32, or sfixed32 to a protobuf message repeated field.
19.321 + *
19.322 + * @param pb protobuf handle.
19.323 + * @param field Field name.
19.324 + * @param value Integer value to add.
19.325 + * @noreturn
19.326 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.327 + */
19.328 +native PbAddInt(Handle:pb, const String:field[], value);
19.329 +
19.330 +/**
19.331 + * Add a float or double to a protobuf message repeated field.
19.332 + *
19.333 + * @param pb protobuf handle.
19.334 + * @param field Field name.
19.335 + * @param value Float value to add.
19.336 + * @noreturn
19.337 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.338 + */
19.339 +native PbAddFloat(Handle:pb, const String:field[], Float:value);
19.340 +
19.341 +/**
19.342 + * Add a bool to a protobuf message repeated field.
19.343 + *
19.344 + * @param pb protobuf handle.
19.345 + * @param field Field name.
19.346 + * @param value Boolean value to add.
19.347 + * @noreturn
19.348 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.349 + */
19.350 +native PbAddBool(Handle:pb, const String:field[], bool:value);
19.351 +
19.352 +/**
19.353 + * Add a string to a protobuf message repeated field.
19.354 + *
19.355 + * @param pb protobuf handle.
19.356 + * @param field Field name.
19.357 + * @param value String value to add.
19.358 + * @noreturn
19.359 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.360 + */
19.361 +native PbAddString(Handle:pb, const String:field[], const String:value[]);
19.362 +
19.363 +/**
19.364 + * Add an RGBA color to a protobuf message repeated field.
19.365 + *
19.366 + * @param pb protobuf handle.
19.367 + * @param field Field name.
19.368 + * @param value Color value to add.
19.369 + * @noreturn
19.370 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.371 + */
19.372 +native PbAddColor(Handle:pb, const String:field[], const color[4]);
19.373 +
19.374 +/**
19.375 + * Add an XYZ angle to a protobuf message repeated field.
19.376 + *
19.377 + * @param pb protobuf handle.
19.378 + * @param field Field name.
19.379 + * @param value Angle value to add.
19.380 + * @noreturn
19.381 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.382 + */
19.383 +native PbAddAngle(Handle:pb, const String:field[], const Float:angle[3]);
19.384 +
19.385 +/**
19.386 + * Add an XYZ vector to a protobuf message repeated field.
19.387 + *
19.388 + * @param pb protobuf handle.
19.389 + * @param field Field name.
19.390 + * @param value Vector value to add.
19.391 + * @noreturn
19.392 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.393 + */
19.394 +native PbAddVector(Handle:pb, const String:field[], const Float:vec[3]);
19.395 +
19.396 +/**
19.397 + * Add an XY vector to a protobuf message repeated field.
19.398 + *
19.399 + * @param pb protobuf handle.
19.400 + * @param field Field name.
19.401 + * @param value Vector value to add.
19.402 + * @noreturn
19.403 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.404 + */
19.405 +native PbAddVector2D(Handle:pb, const String:field[], const Float:vec[2]);
19.406 +
19.407 +/**
19.408 + * Retrieve a handle to an embedded protobuf message in a protobuf message.
19.409 + *
19.410 + * @param pb protobuf handle.
19.411 + * @param field Field name.
19.412 + * @return protobuf handle to embedded message.
19.413 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.414 + */
19.415 +native Handle:PbReadMessage(Handle:pb, const String:field[]);
19.416 +
19.417 +/**
19.418 + * Retrieve a handle to an embedded protobuf message in a protobuf message repeated field.
19.419 + *
19.420 + * @param pb protobuf handle.
19.421 + * @param field Field name.
19.422 + * @param index Index in the repeated field.
19.423 + * @return protobuf handle to embedded message.
19.424 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.425 + */
19.426 +native Handle:PbReadRepeatedMessage(Handle:pb, const String:field[], index);
19.427 +
19.428 +/**
19.429 + * Adds an embedded protobuf message to a protobuf message repeated field.
19.430 + *
19.431 + * @param pb protobuf handle.
19.432 + * @param field Field name.
19.433 + * @return protobuf handle to added, embedded message.
19.434 + * @error Invalid or incorrect Handle, non-existant field, or incorrect field type.
19.435 + */
19.436 +native Handle:PbAddMessage(Handle:pb, const String:field[]);
20.1 --- a/plugins/include/sourcemod.inc Mon Jan 07 09:09:14 2013 -0500
20.2 +++ b/plugins/include/sourcemod.inc Tue Jan 22 21:43:12 2013 -0500
20.3 @@ -66,6 +66,7 @@
20.4 #include <console>
20.5 #include <events>
20.6 #include <bitbuffer>
20.7 +#include <protobuf>
20.8 #include <usermessages>
20.9 #include <menus>
20.10 #include <halflife>
21.1 --- a/plugins/include/usermessages.inc Mon Jan 07 09:09:14 2013 -0500
21.2 +++ b/plugins/include/usermessages.inc Tue Jan 22 21:43:12 2013 -0500
21.3 @@ -44,6 +44,15 @@
21.4 };
21.5
21.6 /**
21.7 + * UserMsg message serialization formats
21.8 + */
21.9 +enum UserMessageType
21.10 +{
21.11 + UM_BitBuf = 0,
21.12 + UM_Protobuf,
21.13 +};
21.14 +
21.15 +/**
21.16 * @section Message Flags.
21.17 */
21.18 #define USERMSG_RELIABLE (1<<2) /**< Message will be set on the reliable stream */
21.19 @@ -55,6 +64,13 @@
21.20 */
21.21
21.22 /**
21.23 + * Returns usermessage serialization type used for the current engine
21.24 + *
21.25 + * @return The supported usermessage type.
21.26 + */
21.27 +native UserMessageType:GetUserMessageType();
21.28 +
21.29 +/**
21.30 * Returns the ID of a given message, or -1 on failure.
21.31 *
21.32 * @param msg String containing message name (case sensitive).
21.33 @@ -115,7 +131,7 @@
21.34 * Called when a message is hooked
21.35 *
21.36 * @param msg_id Message index.
21.37 - * @param bf Handle to the input bit buffer of the message.
21.38 + * @param msg Handle to the input bit buffer or protobuf.
21.39 * @param players Array containing player indexes.
21.40 * @param playersNum Number of players in the array.
21.41 * @param reliable True if message is reliable, false otherwise.
21.42 @@ -124,7 +140,7 @@
21.43 * blocks the message from being sent, and Plugin_Continue
21.44 * resumes normal functionality.
21.45 */
21.46 -functag public Action:MsgHook(UserMsg:msg_id, Handle:bf, const players[], playersNum, bool:reliable, bool:init);
21.47 +functag public Action:MsgHook(UserMsg:msg_id, Handle:msg, const players[], playersNum, bool:reliable, bool:init);
21.48
21.49 /**
21.50 * Called when a message hook has completed.
22.1 --- a/public/IUserMessages.h Mon Jan 07 09:09:14 2013 -0500
22.2 +++ b/public/IUserMessages.h Tue Jan 22 21:43:12 2013 -0500
22.3 @@ -35,19 +35,30 @@
22.4 #include <IShareSys.h>
22.5 #include <sp_vm_api.h>
22.6 #include <IForwardSys.h>
22.7 -#include <bitbuf.h>
22.8 #include <irecipientfilter.h>
22.9
22.10 +namespace google { namespace protobuf {
22.11 + class Message;
22.12 +} };
22.13 +
22.14 +class bf_write;
22.15 +
22.16 /**
22.17 * @file IUserMessages.h
22.18 * @brief Contains functions for advanced usermessage hooking.
22.19 */
22.20
22.21 #define SMINTERFACE_USERMSGS_NAME "IUserMessages"
22.22 -#define SMINTERFACE_USERMSGS_VERSION 3
22.23 +#define SMINTERFACE_USERMSGS_VERSION 4
22.24
22.25 namespace SourceMod
22.26 {
22.27 + enum UserMessageType
22.28 + {
22.29 + UM_BitBuf,
22.30 + UM_Protobuf,
22.31 + };
22.32 +
22.33 /**
22.34 * @brief Listens to user messages sent from the server.
22.35 */
22.36 @@ -55,31 +66,6 @@
22.37 {
22.38 public:
22.39 /**
22.40 - * @brief Called when a hooked user message is being sent
22.41 - * and all interceptions have finished.
22.42 - *
22.43 - * @param msg_id Message Id.
22.44 - * @param bf bf_write structure containing written bytes.
22.45 - * @param pFilter Recipient filter.
22.46 - */
22.47 - virtual void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
22.48 - {
22.49 - }
22.50 -
22.51 - /**
22.52 - * @brief Called when a hooked user message is intercepted.
22.53 - *
22.54 - * @param msg_id Message Id.
22.55 - * @param bf bf_write structure containing written bytes.
22.56 - * @param pFilter Recipient filter.
22.57 - * @return Pl_Continue to allow message, Pl_Stop or Pl_Handled to scrap it.
22.58 - */
22.59 - virtual ResultType InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
22.60 - {
22.61 - return Pl_Continue;
22.62 - }
22.63 -
22.64 - /**
22.65 * @brief Called when a hooked user message is sent, regardless of the hook type.
22.66 *
22.67 * Note: This is called regardless of the API version, though it only happens if the
22.68 @@ -110,6 +96,76 @@
22.69 virtual void OnPostUserMessage(int msg_id, bool sent)
22.70 {
22.71 }
22.72 +
22.73 + virtual UserMessageType GetUserMessageType() const =0;
22.74 + };
22.75 +
22.76 + class IBitBufUserMessageListener : public IUserMessageListener
22.77 + {
22.78 + public:
22.79 + /**
22.80 + * @brief Called when a hooked user message is being sent
22.81 + * and all interceptions have finished.
22.82 + *
22.83 + * @param msg_id Message Id.
22.84 + * @param bf bf_write structure containing written bytes.
22.85 + * @param pFilter Recipient filter.
22.86 + */
22.87 + virtual void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
22.88 + {
22.89 + }
22.90 +
22.91 + /**
22.92 + * @brief Called when a hooked user message is intercepted.
22.93 + *
22.94 + * @param msg_id Message Id.
22.95 + * @param bf bf_write structure containing written bytes.
22.96 + * @param pFilter Recipient filter.
22.97 + * @return Pl_Continue to allow message, Pl_Stop or Pl_Handled to scrap it.
22.98 + */
22.99 + virtual ResultType InterceptUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
22.100 + {
22.101 + return Pl_Continue;
22.102 + }
22.103 +
22.104 + virtual UserMessageType GetUserMessageType() const
22.105 + {
22.106 + return UM_BitBuf;
22.107 + }
22.108 + };
22.109 +
22.110 + class IProtobufUserMessageListener : public IUserMessageListener
22.111 + {
22.112 + public:
22.113 + /**
22.114 + * @brief Called when a hooked user message is being sent
22.115 + * and all interceptions have finished.
22.116 + *
22.117 + * @param msg_id Message Id.
22.118 + * @param msg Protobuf Message structure containing message data.
22.119 + * @param pFilter Recipient filter.
22.120 + */
22.121 + virtual void OnUserMessage(int msg_id, google::protobuf::Message *msg, IRecipientFilter *pFilter)
22.122 + {
22.123 + }
22.124 +
22.125 + /**
22.126 + * @brief Called when a hooked user message is intercepted.
22.127 + *
22.128 + * @param msg_id Message Id.
22.129 + * @param msg Protobuf Message structure containing message data.
22.130 + * @param pFilter Recipient filter.
22.131 + * @return Pl_Continue to allow message, Pl_Stop or Pl_Handled to scrap it.
22.132 + */
22.133 + virtual ResultType InterceptUserMessage(int msg_id, google::protobuf::Message *msg, IRecipientFilter *pFilter)
22.134 + {
22.135 + return Pl_Continue;
22.136 + }
22.137 +
22.138 + virtual UserMessageType GetUserMessageType() const
22.139 + {
22.140 + return UM_Protobuf;
22.141 + }
22.142 };
22.143
22.144 #define USERMSG_RELIABLE (1<<2) /**< Message will be set to reliable */
22.145 @@ -173,7 +229,12 @@
22.146 * @param flags Flags to use for sending the message.
22.147 * @return bf_write structure to write message with, or NULL on failure.
22.148 */
22.149 - virtual bf_write *StartMessage(int msg_id,
22.150 + virtual bf_write *StartBitBufMessage(int msg_id,
22.151 + const cell_t players[],
22.152 + unsigned int playersNum,
22.153 + int flags) =0;
22.154 +
22.155 + virtual google::protobuf::Message *StartProtobufMessage(int msg_id,
22.156 const cell_t players[],
22.157 unsigned int playersNum,
22.158 int flags) =0;
22.159 @@ -218,6 +279,13 @@
22.160 * @return A message index, or -1 on failure.
22.161 */
22.162 virtual bool GetMessageName(int msgid, char *buffer, size_t maxlength) const =0;
22.163 +
22.164 + /**
22.165 + * @brief Returns usermessage serialization type used for the current engine.
22.166 + *
22.167 + * @return The supported usermessage type.
22.168 + */
22.169 + virtual UserMessageType GetUserMessageType() const =0;
22.170 };
22.171 }
22.172