1.1 --- a/core/UserMessages.cpp Mon Jan 07 09:09:14 2013 -0500
1.2 +++ b/core/UserMessages.cpp Tue Jan 22 21:43:12 2013 -0500
1.3 @@ -32,18 +32,32 @@
1.4 #include "UserMessages.h"
1.5 #include "sm_stringutil.h"
1.6
1.7 +#if SOURCE_ENGINE == SE_CSGO
1.8 +#include <cstrike15_usermessage_helpers.h>
1.9 +#endif
1.10 +
1.11 UserMessages g_UserMsgs;
1.12
1.13 +#if SOURCE_ENGINE == SE_CSGO
1.14 +SH_DECL_HOOK3_void(IVEngineServer, SendUserMessage, SH_NOATTRIB, 0, IRecipientFilter &, int, const protobuf::Message &);
1.15 +#else
1.16 #if SOURCE_ENGINE >= SE_LEFT4DEAD
1.17 SH_DECL_HOOK3(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write *, IRecipientFilter *, int, const char *);
1.18 #else
1.19 SH_DECL_HOOK2(IVEngineServer, UserMessageBegin, SH_NOATTRIB, 0, bf_write *, IRecipientFilter *, int);
1.20 #endif
1.21 SH_DECL_HOOK0_void(IVEngineServer, MessageEnd, SH_NOATTRIB, 0);
1.22 +#endif // ==SE_CSGO
1.23
1.24 -UserMessages::UserMessages() : m_InterceptBuffer(m_pBase, 2500)
1.25 +UserMessages::UserMessages()
1.26 +#ifndef USE_PROTOBUF_USERMESSAGES
1.27 + : m_InterceptBuffer(m_pBase, 2500)
1.28 {
1.29 m_Names = sm_trie_create();
1.30 +#else
1.31 + : m_InterceptBuffer(NULL)
1.32 +{
1.33 +#endif
1.34 m_HookCount = 0;
1.35 m_InExec = false;
1.36 m_InHook = false;
1.37 @@ -53,7 +67,9 @@
1.38
1.39 UserMessages::~UserMessages()
1.40 {
1.41 +#ifndef USE_PROTOBUF_USERMESSAGES
1.42 sm_trie_destroy(m_Names);
1.43 +#endif
1.44
1.45 CStack<ListenerInfo *>::iterator iter;
1.46 for (iter=m_FreeListeners.begin(); iter!=m_FreeListeners.end(); iter++)
1.47 @@ -65,8 +81,10 @@
1.48
1.49 void UserMessages::OnSourceModStartup(bool late)
1.50 {
1.51 +#ifndef USE_PROTOBUF_USERMESSAGES
1.52 /* -1 means SourceMM was unable to get the user message list */
1.53 m_FallbackSearch = (g_SMAPI->GetUserMessageCount() == -1);
1.54 +#endif
1.55 }
1.56
1.57 void UserMessages::OnSourceModAllInitialized()
1.58 @@ -78,16 +96,25 @@
1.59 {
1.60 if (m_HookCount)
1.61 {
1.62 +#if SOURCE_ENGINE == SE_CSGO
1.63 + SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Pre, false);
1.64 + SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Post, true);
1.65 +#else
1.66 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Pre, false);
1.67 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Post, true);
1.68 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Pre, false);
1.69 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Post, true);
1.70 +#endif
1.71 }
1.72 m_HookCount = 0;
1.73 }
1.74
1.75 int UserMessages::GetMessageIndex(const char *msg)
1.76 {
1.77 +#if SOURCE_ENGINE == SE_CSGO
1.78 + // Can split this per engine and/or game later
1.79 + return g_Cstrike15UsermessageHelpers.GetIndex(msg);
1.80 +#else
1.81 int msgid;
1.82
1.83 if (!sm_trie_retrieve(m_Names, msg, reinterpret_cast<void **>(&msgid)))
1.84 @@ -118,10 +145,19 @@
1.85 }
1.86
1.87 return msgid;
1.88 +#endif
1.89 }
1.90
1.91 bool UserMessages::GetMessageName(int msgid, char *buffer, size_t maxlength) const
1.92 {
1.93 +#if SOURCE_ENGINE == SE_CSGO
1.94 + const char *pszName = g_Cstrike15UsermessageHelpers.GetName(msgid);
1.95 + if (!pszName)
1.96 + return false;
1.97 +
1.98 + strncopy(buffer, pszName, maxlength);
1.99 + return true;
1.100 +#else
1.101 if (m_FallbackSearch)
1.102 {
1.103 int size;
1.104 @@ -137,10 +173,14 @@
1.105 }
1.106
1.107 return false;
1.108 +#endif
1.109 }
1.110
1.111 -bf_write *UserMessages::StartMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags)
1.112 +bf_write *UserMessages::StartBitBufMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags)
1.113 {
1.114 +#ifdef USE_PROTOBUF_USERMESSAGES
1.115 + return NULL;
1.116 +#else
1.117 bf_write *buffer;
1.118
1.119 if (m_InExec || m_InHook)
1.120 @@ -182,6 +222,68 @@
1.121 }
1.122
1.123 return buffer;
1.124 +#endif // USE_PROTOBUF_USERMESSAGES
1.125 +}
1.126 +
1.127 +google::protobuf::Message *UserMessages::StartProtobufMessage(int msg_id, const cell_t players[], unsigned int playersNum, int flags)
1.128 +{
1.129 +#ifndef USE_PROTOBUF_USERMESSAGES
1.130 + return NULL;
1.131 +#else
1.132 + protobuf::Message *buffer;
1.133 +
1.134 + if (m_InExec || m_InHook)
1.135 + {
1.136 + return NULL;
1.137 + }
1.138 + if (msg_id < 0 || msg_id >= 255)
1.139 + {
1.140 + return NULL;
1.141 + }
1.142 +
1.143 + m_CurId = msg_id;
1.144 + m_CellRecFilter.Initialize(players, playersNum);
1.145 +
1.146 + m_CurFlags = flags;
1.147 + if (m_CurFlags & USERMSG_INITMSG)
1.148 + {
1.149 + m_CellRecFilter.SetToInit(true);
1.150 + }
1.151 + if (m_CurFlags & USERMSG_RELIABLE)
1.152 + {
1.153 + m_CellRecFilter.SetToReliable(true);
1.154 + }
1.155 +
1.156 + m_InExec = true;
1.157 +
1.158 + if (m_CurFlags & USERMSG_BLOCKHOOKS)
1.159 + {
1.160 + // direct message creation, return buffer "from engine". keep track
1.161 + m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_id)->New();
1.162 + buffer = m_FakeEngineBuffer;
1.163 + } else {
1.164 + protobuf::Message *msg = OnStartMessage_Pre(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id, g_SMAPI->GetUserMessage(msg_id));
1.165 + switch (m_FakeMetaRes)
1.166 + {
1.167 + case MRES_IGNORED:
1.168 + case MRES_HANDLED:
1.169 + m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_id)->New();
1.170 + buffer = m_FakeEngineBuffer;
1.171 + break;
1.172 +
1.173 + case MRES_OVERRIDE:
1.174 + m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_id)->New();
1.175 + // fallthrough
1.176 + case MRES_SUPERCEDE:
1.177 + buffer = msg;
1.178 + break;
1.179 + }
1.180 +
1.181 + OnStartMessage_Post(static_cast<IRecipientFilter *>(&m_CellRecFilter), msg_id, g_SMAPI->GetUserMessage(msg_id));
1.182 + }
1.183 +
1.184 + return buffer;
1.185 +#endif // USE_PROTOBUF_USERMESSAGES
1.186 }
1.187
1.188 bool UserMessages::EndMessage()
1.189 @@ -191,12 +293,37 @@
1.190 return false;
1.191 }
1.192
1.193 +#if SOURCE_ENGINE == SE_CSGO
1.194 + if (m_CurFlags & USERMSG_BLOCKHOOKS)
1.195 + {
1.196 + ENGINE_CALL(SendUserMessage)(static_cast<IRecipientFilter &>(m_CellRecFilter), m_CurId, *m_FakeEngineBuffer);
1.197 + delete m_FakeEngineBuffer;
1.198 + m_FakeEngineBuffer = NULL;
1.199 + } else {
1.200 + OnMessageEnd_Pre();
1.201 +
1.202 + switch (m_FakeMetaRes)
1.203 + {
1.204 + case MRES_IGNORED:
1.205 + case MRES_HANDLED:
1.206 + case MRES_OVERRIDE:
1.207 + engine->SendUserMessage(static_cast<IRecipientFilter &>(m_CellRecFilter), m_CurId, *m_FakeEngineBuffer);
1.208 + delete m_FakeEngineBuffer;
1.209 + m_FakeEngineBuffer = NULL;
1.210 + break;
1.211 + //case MRES_SUPERCEDE:
1.212 + }
1.213 +
1.214 + OnMessageEnd_Post();
1.215 + }
1.216 +#else
1.217 if (m_CurFlags & USERMSG_BLOCKHOOKS)
1.218 {
1.219 ENGINE_CALL(MessageEnd)();
1.220 } else {
1.221 engine->MessageEnd();
1.222 }
1.223 +#endif // SE_CSGO
1.224
1.225 m_InExec = false;
1.226 m_CurFlags = 0;
1.227 @@ -205,31 +332,60 @@
1.228 return true;
1.229 }
1.230
1.231 +UserMessageType UserMessages::GetUserMessageType() const
1.232 +{
1.233 +#ifdef USE_PROTOBUF_USERMESSAGES
1.234 + return UM_Protobuf;
1.235 +#else
1.236 + return UM_BitBuf;
1.237 +#endif
1.238 +}
1.239 +
1.240 bool UserMessages::HookUserMessage2(int msg_id,
1.241 IUserMessageListener *pListener,
1.242 bool intercept)
1.243 {
1.244 - return InternalHook(msg_id, pListener, intercept, true);
1.245 +#ifdef USE_PROTOBUF_USERMESSAGES
1.246 + return InternalHook(msg_id, (IProtobufUserMessageListener *)pListener, intercept, true);
1.247 +#else
1.248 + return InternalHook(msg_id, (IBitBufUserMessageListener *)pListener, intercept, true);
1.249 +#endif
1.250 }
1.251
1.252 bool UserMessages::UnhookUserMessage2(int msg_id,
1.253 IUserMessageListener *pListener,
1.254 bool intercept)
1.255 {
1.256 - return InternalUnhook(msg_id, pListener, intercept, true);
1.257 +#ifdef USE_PROTOBUF_USERMESSAGES
1.258 + return InternalUnhook(msg_id, (IProtobufUserMessageListener *)pListener, intercept, true);
1.259 +#else
1.260 + return InternalUnhook(msg_id, (IBitBufUserMessageListener *)pListener, intercept, true);
1.261 +#endif
1.262 }
1.263
1.264 bool UserMessages::HookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
1.265 {
1.266 - return InternalHook(msg_id, pListener, intercept, false);
1.267 +#ifdef USE_PROTOBUF_USERMESSAGES
1.268 + return InternalHook(msg_id, (IProtobufUserMessageListener *)pListener, intercept, false);
1.269 +#else
1.270 + return InternalHook(msg_id, (IBitBufUserMessageListener *)pListener, intercept, false);
1.271 +#endif
1.272 }
1.273
1.274 bool UserMessages::UnhookUserMessage(int msg_id, IUserMessageListener *pListener, bool intercept)
1.275 {
1.276 - return InternalUnhook(msg_id, pListener, intercept, false);
1.277 +#ifdef USE_PROTOBUF_USERMESSAGES
1.278 + return InternalUnhook(msg_id, (IProtobufUserMessageListener *)pListener, intercept, false);
1.279 +#else
1.280 + return InternalUnhook(msg_id, (IBitBufUserMessageListener *)pListener, intercept, false);
1.281 +#endif
1.282 }
1.283
1.284 -bool UserMessages::InternalHook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew)
1.285 +#ifdef USE_PROTOBUF_USERMESSAGES
1.286 +bool UserMessages::InternalHook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew)
1.287 +#else
1.288 +bool UserMessages::InternalHook(int msg_id, IBitBufUserMessageListener *pListener, bool intercept, bool isNew)
1.289 +#endif
1.290 {
1.291 if (msg_id < 0 || msg_id >= 255)
1.292 {
1.293 @@ -252,10 +408,15 @@
1.294
1.295 if (!m_HookCount++)
1.296 {
1.297 +#if SOURCE_ENGINE == SE_CSGO
1.298 + SH_ADD_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Pre, false);
1.299 + SH_ADD_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Post, true);
1.300 +#else
1.301 SH_ADD_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Pre, false);
1.302 SH_ADD_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Post, true);
1.303 SH_ADD_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Pre, false);
1.304 SH_ADD_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Post, true);
1.305 +#endif
1.306 }
1.307
1.308 if (intercept)
1.309 @@ -268,7 +429,11 @@
1.310 return true;
1.311 }
1.312
1.313 -bool UserMessages::InternalUnhook(int msg_id, IUserMessageListener *pListener, bool intercept, bool isNew)
1.314 +#ifdef USE_PROTOBUF_USERMESSAGES
1.315 +bool UserMessages::InternalUnhook(int msg_id, IProtobufUserMessageListener *pListener, bool intercept, bool isNew)
1.316 +#else
1.317 +bool UserMessages::InternalUnhook(int msg_id, IBitBufUserMessageListener *pListener, bool intercept, bool isNew)
1.318 +#endif
1.319 {
1.320 MsgList *pList;
1.321 MsgIter iter;
1.322 @@ -309,14 +474,167 @@
1.323 {
1.324 if (--m_HookCount == 0)
1.325 {
1.326 +#if SOURCE_ENGINE == SE_CSGO
1.327 + SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Pre, false);
1.328 + SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, SendUserMessage, engine, this, &UserMessages::OnSendUserMessage_Post, true);
1.329 +#else
1.330 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Pre, false);
1.331 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, UserMessageBegin, engine, this, &UserMessages::OnStartMessage_Post, true);
1.332 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Pre, false);
1.333 SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, MessageEnd, engine, this, &UserMessages::OnMessageEnd_Post, true);
1.334 +#endif
1.335 }
1.336 }
1.337
1.338 -#if SOURCE_ENGINE >= SE_LEFT4DEAD
1.339 +#ifdef USE_PROTOBUF_USERMESSAGES
1.340 +// Unlike protobuf's Message::CopyFrom:
1.341 +// - Does not require to/from message descriptors to be identical.
1.342 +// - Fields are copied by name, rather than index.
1.343 +// - String fields are retrieved for copy with GetStringReference, to avoid destucting libprotobuf std::string in sm.
1.344 +// - Unknown fields in |from| message are not copied to |to| message.
1.345 +// - Copying Message fields recursively calls this function, rather than Message::MergeFrom.
1.346 +static void _CopyProtobufMessage(const protobuf::Message &from, protobuf::Message *to)
1.347 +{
1.348 + const protobuf::Descriptor* descriptor = from.GetDescriptor();
1.349 +
1.350 + const protobuf::Reflection* from_reflection = from.GetReflection();
1.351 + const protobuf::Reflection* to_reflection = to->GetReflection();
1.352 +
1.353 + protobuf::UnknownFieldSet toUnknownFields;
1.354 +
1.355 + int fromFieldCount = descriptor->field_count();
1.356 + for (int i = 0; i < fromFieldCount; i++)
1.357 + {
1.358 + const protobuf::FieldDescriptor* fromField = descriptor->field(i);
1.359 + const protobuf::FieldDescriptor* toField = to->GetDescriptor()->FindFieldByName(fromField->name());
1.360 +
1.361 + // This will stripped new fields off of intercepted usermessages.
1.362 + // TODO: fix that.
1.363 + if (!toField)
1.364 + {
1.365 + continue;
1.366 + }
1.367 +
1.368 + if (fromField->is_repeated())
1.369 + {
1.370 + int count = from_reflection->FieldSize(from, fromField);
1.371 + for (int j = 0; j < count; j++)
1.372 + {
1.373 + switch (fromField->cpp_type())
1.374 + {
1.375 +#define HANDLE_TYPE(CPPTYPE, METHOD) \
1.376 + case protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \
1.377 + to_reflection->Add##METHOD(to, toField, \
1.378 + from_reflection->GetRepeated##METHOD(from, fromField, j)); \
1.379 + break;
1.380 + HANDLE_TYPE(INT32 , Int32 );
1.381 + HANDLE_TYPE(INT64 , Int64 );
1.382 + HANDLE_TYPE(UINT32, UInt32);
1.383 + HANDLE_TYPE(UINT64, UInt64);
1.384 + HANDLE_TYPE(FLOAT , Float );
1.385 + HANDLE_TYPE(DOUBLE, Double);
1.386 + HANDLE_TYPE(BOOL , Bool );
1.387 + HANDLE_TYPE(ENUM , Enum );
1.388 +#undef HANDLE_TYPE
1.389 + case protobuf::FieldDescriptor::CPPTYPE_STRING:
1.390 + {
1.391 + std::string buffer;
1.392 + to_reflection->AddString(to, toField,
1.393 + from_reflection->GetRepeatedStringReference(from, fromField, j, &buffer));
1.394 + }
1.395 + break;
1.396 + case protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
1.397 + _CopyProtobufMessage(
1.398 + from_reflection->GetRepeatedMessage(from, fromField, j),
1.399 + to_reflection->AddMessage(to, toField)
1.400 + );
1.401 + break;
1.402 + }
1.403 + }
1.404 + }
1.405 + else
1.406 + {
1.407 + switch (fromField->cpp_type())
1.408 + {
1.409 +#define HANDLE_TYPE(CPPTYPE, METHOD) \
1.410 + case protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \
1.411 + to_reflection->Set##METHOD(to, toField, \
1.412 + from_reflection->Get##METHOD(from, fromField)); \
1.413 + break;
1.414 + HANDLE_TYPE(INT32 , Int32 );
1.415 + HANDLE_TYPE(INT64 , Int64 );
1.416 + HANDLE_TYPE(UINT32, UInt32);
1.417 + HANDLE_TYPE(UINT64, UInt64);
1.418 + HANDLE_TYPE(FLOAT , Float );
1.419 + HANDLE_TYPE(DOUBLE, Double);
1.420 + HANDLE_TYPE(BOOL , Bool );
1.421 + HANDLE_TYPE(ENUM , Enum );
1.422 +#undef HANDLE_TYPE
1.423 + case protobuf::FieldDescriptor::CPPTYPE_STRING:
1.424 + {
1.425 + std::string buffer;
1.426 + to_reflection->SetString(to, toField,
1.427 + from_reflection->GetStringReference(from, fromField, &buffer));
1.428 + }
1.429 + break;
1.430 + case protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
1.431 + _CopyProtobufMessage(
1.432 + from_reflection->GetMessage(from, fromField),
1.433 + to_reflection->MutableMessage(to, toField)
1.434 + );
1.435 + break;
1.436 + }
1.437 + }
1.438 + }
1.439 +}
1.440 +#endif
1.441 +
1.442 +#if SOURCE_ENGINE == SE_CSGO
1.443 +void UserMessages::OnSendUserMessage_Pre(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg)
1.444 +{
1.445 + OnStartMessage_Pre(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
1.446 + if (m_FakeMetaRes == MRES_SUPERCEDE)
1.447 + {
1.448 + _CopyProtobufMessage(msg, m_InterceptBuffer);
1.449 + }
1.450 + else
1.451 + {
1.452 + OnStartMessage_Post(&filter, msg_type, g_Cstrike15UsermessageHelpers.GetName(msg_type));
1.453 + }
1.454 +
1.455 + OnMessageEnd_Pre();
1.456 + if (m_FakeMetaRes == MRES_SUPERCEDE)
1.457 + RETURN_META(MRES_SUPERCEDE);
1.458 +
1.459 + RETURN_META(MRES_IGNORED);
1.460 +}
1.461 +
1.462 +void UserMessages::OnSendUserMessage_Post(IRecipientFilter &filter, int msg_type, const protobuf::Message &msg)
1.463 +{
1.464 + OnMessageEnd_Post();
1.465 + RETURN_META(MRES_IGNORED);
1.466 +}
1.467 +#endif
1.468 +
1.469 +#ifdef USE_PROTOBUF_USERMESSAGES
1.470 +#define UM_RETURN_META_VALUE(res, val) \
1.471 + m_FakeMetaRes = res; \
1.472 + return val;
1.473 +
1.474 +#define UM_RETURN_META(res) \
1.475 + m_FakeMetaRes = res; \
1.476 + return;
1.477 +#else
1.478 +#define UM_RETURN_META_VALUE(res, val) \
1.479 + RETURN_META_VALUE(res, val)
1.480 +
1.481 +#define UM_RETURN_META(res) \
1.482 + RETURN_META(res)
1.483 +#endif
1.484 +
1.485 +#if SOURCE_ENGINE == SE_CSGO
1.486 +protobuf::Message *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
1.487 +#elif SOURCE_ENGINE >= SE_LEFT4DEAD
1.488 bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type, const char *msg_name)
1.489 #else
1.490 bf_write *UserMessages::OnStartMessage_Pre(IRecipientFilter *filter, int msg_type)
1.491 @@ -329,7 +647,7 @@
1.492 || (m_InExec && (m_CurFlags & USERMSG_BLOCKHOOKS)))
1.493 {
1.494 m_InHook = false;
1.495 - RETURN_META_VALUE(MRES_IGNORED, NULL);
1.496 + UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
1.497 }
1.498
1.499 m_CurId = msg_type;
1.500 @@ -339,14 +657,23 @@
1.501
1.502 if (!is_intercept_empty)
1.503 {
1.504 +#ifdef USE_PROTOBUF_USERMESSAGES
1.505 + if (m_InterceptBuffer)
1.506 + delete m_InterceptBuffer;
1.507 + m_InterceptBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_type)->New();
1.508 + UM_RETURN_META_VALUE(MRES_SUPERCEDE, m_InterceptBuffer);
1.509 +#else
1.510 m_InterceptBuffer.Reset();
1.511 - RETURN_META_VALUE(MRES_SUPERCEDE, &m_InterceptBuffer);
1.512 + UM_RETURN_META_VALUE(MRES_SUPERCEDE, &m_InterceptBuffer);
1.513 +#endif
1.514 }
1.515
1.516 - RETURN_META_VALUE(MRES_IGNORED, NULL);
1.517 + UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
1.518 }
1.519
1.520 -#if SOURCE_ENGINE >= SE_LEFT4DEAD
1.521 +#if SOURCE_ENGINE == SE_CSGO
1.522 +protobuf::Message *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
1.523 +#elif SOURCE_ENGINE >= SE_LEFT4DEAD
1.524 bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type, const char *msg_name)
1.525 #else
1.526 bf_write *UserMessages::OnStartMessage_Post(IRecipientFilter *filter, int msg_type)
1.527 @@ -354,19 +681,24 @@
1.528 {
1.529 if (!m_InHook)
1.530 {
1.531 - RETURN_META_VALUE(MRES_IGNORED, NULL);
1.532 + UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
1.533 }
1.534
1.535 +#ifdef USE_PROTOBUF_USERMESSAGES
1.536 + m_FakeEngineBuffer = g_Cstrike15UsermessageHelpers.GetPrototype(msg_type)->New();
1.537 + m_OrigBuffer = m_FakeEngineBuffer;
1.538 +#else
1.539 m_OrigBuffer = META_RESULT_ORIG_RET(bf_write *);
1.540 +#endif
1.541
1.542 - RETURN_META_VALUE(MRES_IGNORED, NULL);
1.543 + UM_RETURN_META_VALUE(MRES_IGNORED, NULL);
1.544 }
1.545
1.546 void UserMessages::OnMessageEnd_Post()
1.547 {
1.548 if (!m_InHook)
1.549 {
1.550 - RETURN_META(MRES_IGNORED);
1.551 + UM_RETURN_META(MRES_IGNORED);
1.552 }
1.553
1.554 MsgList *pList;
1.555 @@ -434,7 +766,7 @@
1.556 {
1.557 if (!m_InHook)
1.558 {
1.559 - RETURN_META(MRES_IGNORED);
1.560 + UM_RETURN_META(MRES_IGNORED);
1.561 }
1.562
1.563 MsgList *pList;
1.564 @@ -450,7 +782,11 @@
1.565 {
1.566 pInfo = (*iter);
1.567 pInfo->IsHooked = true;
1.568 +#ifdef USE_PROTOBUF_USERMESSAGES
1.569 + res = pInfo->Callback->InterceptUserMessage(m_CurId, m_InterceptBuffer, m_CurRecFilter);
1.570 +#else
1.571 res = pInfo->Callback->InterceptUserMessage(m_CurId, &m_InterceptBuffer, m_CurRecFilter);
1.572 +#endif
1.573
1.574 intercepted = true;
1.575
1.576 @@ -498,8 +834,12 @@
1.577
1.578 if (!handled && intercepted)
1.579 {
1.580 +#if SOURCE_ENGINE == SE_CSGO
1.581 + ENGINE_CALL(SendUserMessage)(static_cast<IRecipientFilter &>(*m_CurRecFilter), m_CurId, *m_InterceptBuffer);
1.582 + delete m_InterceptBuffer;
1.583 + m_InterceptBuffer = NULL;
1.584 +#else
1.585 bf_write *engine_bfw;
1.586 -
1.587 #if SOURCE_ENGINE >= SE_LEFT4DEAD
1.588 engine_bfw = ENGINE_CALL(UserMessageBegin)(m_CurRecFilter, m_CurId, g_SMAPI->GetUserMessage(m_CurId));
1.589 #else
1.590 @@ -508,6 +848,7 @@
1.591 m_ReadBuffer.StartReading(m_InterceptBuffer.GetBasePointer(), m_InterceptBuffer.GetNumBytesWritten());
1.592 engine_bfw->WriteBitsFromBuffer(&m_ReadBuffer, m_InterceptBuffer.GetNumBitsWritten());
1.593 ENGINE_CALL(MessageEnd)();
1.594 +#endif // SE_CSGO
1.595 }
1.596
1.597 pList = &m_msgHooks[m_CurId];
1.598 @@ -529,8 +870,8 @@
1.599 iter++;
1.600 }
1.601
1.602 - RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED);
1.603 + UM_RETURN_META((intercepted) ? MRES_SUPERCEDE : MRES_IGNORED);
1.604 supercede:
1.605 m_BlockEndPost = true;
1.606 - RETURN_META(MRES_SUPERCEDE);
1.607 + UM_RETURN_META(MRES_SUPERCEDE);
1.608 }