diff options
Diffstat (limited to 'protocols/Steam/src')
-rw-r--r-- | protocols/Steam/src/protobuf-c/protobuf-c-text.c | 501 | ||||
-rw-r--r-- | protocols/Steam/src/protobuf-c/protobuf-c-text.h | 213 | ||||
-rw-r--r-- | protocols/Steam/src/stdafx.h | 5 | ||||
-rw-r--r-- | protocols/Steam/src/steam_ws.cpp | 2 |
4 files changed, 720 insertions, 1 deletions
diff --git a/protocols/Steam/src/protobuf-c/protobuf-c-text.c b/protocols/Steam/src/protobuf-c/protobuf-c-text.c new file mode 100644 index 0000000000..6cbc9b46e7 --- /dev/null +++ b/protocols/Steam/src/protobuf-c/protobuf-c-text.c @@ -0,0 +1,501 @@ +/** \file + * Routines to generate text format protobufs. + * + * This file contains the internal support functions as well as the + * exported functions which are used to generate text format protobufs + * from C protobuf data types. + * + * \author Kevin Lyda <kevin@ie.suberic.net> + * \date March 2014 + */ + +#include <sys/types.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include "protobuf-c.h" +#include "protobuf-c-text.h" +#include "protobuf-c-util.h" + +/** A dynamic string struct. + * + * Used to track additions to a growing string and memory allocation + * errors that occur in processing + */ +typedef struct _ReturnString { + int malloc_err; /**< Set to 1 when there's been a malloc error. */ + int allocated; /**< Size of allocated string. */ + int pos; /**< Current end of the string. */ + char *s; /**< The string. */ +} ReturnString; + +/** Append a string to the ReturnString. + * + * Append the string built from \c format and its args to the \c rs + * string. Note that \c malloc_err is checked and if it's true, + * this function won't do anything. + * + * \param[in,out] rs The string to append to. + * \param[in] guess A guess at the number of chars being added. + * \param[in] allocator allocator functions. + * \param[in] format Printf-style format string. + * \param[in] ... Variable number of args for \c format. + */ + +static void +rs_append(ReturnString *rs, int guess, + ProtobufCAllocator *allocator, + const char *format, ...) +{ + va_list args; + int added; + + if (rs->malloc_err) { + return; + } + + if (rs->allocated - rs->pos < guess * 2) { + char *tmp; + + tmp = PBC_ALLOC(rs->allocated + guess * 2); + if (!tmp) { + PBC_FREE(rs->s); + rs->s = NULL; + rs->malloc_err = 1; + return; + } + memcpy(tmp, rs->s, rs->allocated); + PBC_FREE(rs->s); + rs->s = tmp; + rs->allocated += guess * 2; + } + va_start(args, format); + added = vsnprintf(rs->s + rs->pos, rs->allocated - rs->pos, format, args); + va_end(args); + rs->pos += added; + return; +} + +/** @} */ /* End of utility group. */ + + +/** \defgroup generate Functions to generate text format proto bufs + * \ingroup internal + * @{ + */ + +/** Escape string. + * + * Add escape characters to strings for problematic characters. + * + * \param[in] src The unescaped string to process. + * \param[in] len Length of \c src. Note that \c src might have ASCII + * \c NULs so strlen() isn't good enough here. + * \param[in] allocator allocator functions. + * \return The fully escaped string, or \c NULL if there has been an + * allocation error. + */ +static char * +esc_str(char *src, int len, ProtobufCAllocator *allocator) +{ + int i, escapes = 0, dst_len = 0; + unsigned char *dst; + + for (i = 0; i < len; i++) { + if (!isprint(src[i])) { + escapes++; + } + } + dst = PBC_ALLOC((escapes * 4) + ((len - escapes) * 2) + 1); + if (!dst) { + return NULL; + } + + for (i = 0; i < len; i++) { + switch (src[i]) { + /* Special cases. */ + case '\'': + dst[dst_len++] = '\\'; + dst[dst_len++] = '\''; + break; + case '\"': + dst[dst_len++] = '\\'; + dst[dst_len++] = '\"'; + break; + case '\\': + dst[dst_len++] = '\\'; + dst[dst_len++] = '\\'; + break; + case '\n': + dst[dst_len++] = '\\'; + dst[dst_len++] = 'n'; + break; + case '\r': + dst[dst_len++] = '\\'; + dst[dst_len++] = 'r'; + break; + case '\t': + dst[dst_len++] = '\\'; + dst[dst_len++] = 't'; + break; + + /* Escape with octal if !isprint. */ + default: + if (!isprint(src[i])) { + dst_len += sprintf(dst + dst_len, "\\%03o", src[i]); + } else { + dst[dst_len++] = src[i]; + } + break; + } + } + dst[dst_len] = '\0'; + + return dst; +} + +/** Internal function to back API function. + * + * Has a few extra params to better enable recursion. This function gets + * called for each nested message as the \c ProtobufCMessage struct is + * traversed. + * + * \param[in,out] rs The string being built up for the text format protobuf. + * \param[in] level Indent level - increments in 2's. + * \param[in] m The \c ProtobufCMessage being serialised. + * \param[in] d The descriptor for the \c ProtobufCMessage. + * \param[in] allocator allocator functions. + */ +static void +protobuf_c_text_to_string_internal(ReturnString *rs, + int level, + ProtobufCMessage *m, + const ProtobufCMessageDescriptor *d, + ProtobufCAllocator *allocator) +{ + int i; + size_t j, quantifier_offset; + double float_var; + const ProtobufCFieldDescriptor *f; + ProtobufCEnumDescriptor *enumd; + const ProtobufCEnumValue *enumv; + + f = d->fields; + for (i = 0; i < d->n_fields; i++) { + if (rs->malloc_err) { + /* If there's been a malloc error, go die. */ + return; + } + + /* Decide if something needs to be done for this field. */ + switch (f[i].label) { + case PROTOBUF_C_LABEL_OPTIONAL: + if (f[i].type == PROTOBUF_C_TYPE_STRING) { + if (!STRUCT_MEMBER(char *, m, f[i].offset) + || (STRUCT_MEMBER(char *, m, f[i].offset) + == (char *)f[i].default_value)) { + continue; + } + } else if (f[i].type == PROTOBUF_C_TYPE_MESSAGE) { + if (!STRUCT_MEMBER(char *, m, f[i].offset)) { + continue; + } + } else { + if (!STRUCT_MEMBER(protobuf_c_boolean, m, f[i].quantifier_offset)) { + continue; + } + } + break; + case PROTOBUF_C_LABEL_REPEATED: + if (!STRUCT_MEMBER(size_t, m, f[i].quantifier_offset)) { + continue; + } + break; + } + + quantifier_offset = STRUCT_MEMBER(size_t, m, f[i].quantifier_offset); + /* Field exists and has data, dump it. */ + switch (f[i].type) { + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_FIXED32: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %u\n", + level, "", f[i].name, + STRUCT_MEMBER(uint32_t *, m, f[i].offset)[j]); + } + } else { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %u\n", + level, "", f[i].name, + STRUCT_MEMBER(uint32_t, m, f[i].offset)); + } + break; + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_SFIXED32: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %d\n", + level, "", f[i].name, + STRUCT_MEMBER(int32_t *, m, f[i].offset)[j]); + } + } else { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %d\n", + level, "", f[i].name, + STRUCT_MEMBER(int32_t, m, f[i].offset)); + } + break; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + case PROTOBUF_C_TYPE_FIXED64: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %lu\n", + level, "", f[i].name, + STRUCT_MEMBER(uint64_t *, m, f[i].offset)[j]); + } + } else { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %lu\n", + level, "", f[i].name, + STRUCT_MEMBER(uint64_t, m, f[i].offset)); + } + break; + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_SFIXED64: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %ld\n", + level, "", f[i].name, + STRUCT_MEMBER(int64_t *, m, f[i].offset)[j]); + } + } else { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %ld\n", + level, "", f[i].name, + STRUCT_MEMBER(int64_t, m, f[i].offset)); + } + break; + case PROTOBUF_C_TYPE_FLOAT: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + float_var = STRUCT_MEMBER(float *, m, f[i].offset)[j]; + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %g\n", + level, "", f[i].name, + float_var); + } + } else { + float_var = STRUCT_MEMBER(float, m, f[i].offset); + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %g\n", + level, "", f[i].name, + float_var); + } + break; + case PROTOBUF_C_TYPE_DOUBLE: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %g\n", + level, "", f[i].name, + STRUCT_MEMBER(double *, m, f[i].offset)[j]); + } + } else { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %g\n", + level, "", f[i].name, + STRUCT_MEMBER(double, m, f[i].offset)); + } + break; + case PROTOBUF_C_TYPE_BOOL: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %s\n", + level, "", f[i].name, + STRUCT_MEMBER(protobuf_c_boolean *, m, f[i].offset)[j]? + "true": "false"); + } + } else { + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %s\n", + level, "", f[i].name, + STRUCT_MEMBER(protobuf_c_boolean, m, f[i].offset)? + "true": "false"); + } + break; + case PROTOBUF_C_TYPE_ENUM: + enumd = (ProtobufCEnumDescriptor *)f[i].descriptor; + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + enumv = protobuf_c_enum_descriptor_get_value( + enumd, STRUCT_MEMBER(int *, m, f[i].offset)[j]); + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %s\n", + level, "", f[i].name, + enumv? enumv->name: "unknown"); + } + } else { + enumv = protobuf_c_enum_descriptor_get_value( + enumd, STRUCT_MEMBER(int, m, f[i].offset)); + rs_append(rs, level + strlen(f[i].name) + 20, + allocator, + "%*s%s: %s\n", + level, "", f[i].name, + enumv? enumv->name: "unknown"); + } + break; + case PROTOBUF_C_TYPE_STRING: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + unsigned char *escaped; + + escaped = esc_str( + STRUCT_MEMBER(unsigned char **, m, f[i].offset)[j], + strlen(STRUCT_MEMBER(unsigned char **, m, f[i].offset)[j]), + allocator); + if (!escaped) { + PBC_FREE(rs->s); + rs->s = NULL; + rs->malloc_err = 1; + return; + } + rs_append(rs, level + strlen(f[i].name) + strlen(escaped) + 10, + allocator, + "%*s%s: \"%s\"\n", level, "", f[i].name, escaped); + PBC_FREE(escaped); + } + } else { + unsigned char *escaped; + + escaped = esc_str(STRUCT_MEMBER(unsigned char *, m, f[i].offset), + strlen(STRUCT_MEMBER(unsigned char *, m, f[i].offset)), + allocator); + if (!escaped) { + PBC_FREE(rs->s); + rs->s = NULL; + rs->malloc_err = 1; + return; + } + rs_append(rs, level + strlen(f[i].name) + strlen(escaped) + 10, + allocator, + "%*s%s: \"%s\"\n", level, "", f[i].name, escaped); + PBC_FREE(escaped); + } + break; + case PROTOBUF_C_TYPE_BYTES: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; j < quantifier_offset; j++) { + unsigned char *escaped; + + escaped = esc_str( + STRUCT_MEMBER(ProtobufCBinaryData *, m, f[i].offset)[j].data, + STRUCT_MEMBER(ProtobufCBinaryData *, m, f[i].offset)[j].len, + allocator); + if (!escaped) { + PBC_FREE(rs->s); + rs->s = NULL; + rs->malloc_err = 1; + return; + } + rs_append(rs, level + strlen(f[i].name) + strlen(escaped) + 10, + allocator, + "%*s%s: \"%s\"\n", level, "", f[i].name, escaped); + PBC_FREE(escaped); + } + } else { + unsigned char *escaped; + + escaped = esc_str( + STRUCT_MEMBER(ProtobufCBinaryData, m, f[i].offset).data, + STRUCT_MEMBER(ProtobufCBinaryData, m, f[i].offset).len, + allocator); + if (!escaped) { + PBC_FREE(rs->s); + rs->s = NULL; + rs->malloc_err = 1; + return; + } + rs_append(rs, level + strlen(f[i].name) + strlen(escaped) + 10, + allocator, + "%*s%s: \"%s\"\n", level, "", f[i].name, escaped); + PBC_FREE(escaped); + } + break; + + case PROTOBUF_C_TYPE_MESSAGE: + if (f[i].label == PROTOBUF_C_LABEL_REPEATED) { + for (j = 0; + j < STRUCT_MEMBER(size_t, m, f[i].quantifier_offset); + j++) { + rs_append(rs, level + strlen(f[i].name) + 10, + allocator, + "%*s%s {\n", level, "", f[i].name); + protobuf_c_text_to_string_internal(rs, level + 2, + STRUCT_MEMBER(ProtobufCMessage **, m, f[i].offset)[j], + (ProtobufCMessageDescriptor *)f[i].descriptor, + allocator); + rs_append(rs, level + 10, + allocator, + "%*s}\n", level, ""); + } + } else { + rs_append(rs, level + strlen(f[i].name) + 10, + allocator, + "%*s%s {\n", level, "", f[i].name); + protobuf_c_text_to_string_internal(rs, level + 2, + STRUCT_MEMBER(ProtobufCMessage *, m, f[i].offset), + (ProtobufCMessageDescriptor *)f[i].descriptor, + allocator); + rs_append(rs, level + 10, + allocator, + "%*s}\n", level, ""); + } + break; + default: + PBC_FREE(rs->s); + rs->s = NULL; + return; + break; + } + + } +} + +/** @} */ /* End of generate group. */ + +/* See .h file for API docs. */ + +char * +protobuf_c_text_to_string(ProtobufCMessage *m, + ProtobufCAllocator *allocator) +{ + ReturnString rs = { 0, 0, 0, NULL }; + + protobuf_c_text_to_string_internal(&rs, 0, m, m->descriptor, allocator); + + return rs.s; +} diff --git a/protocols/Steam/src/protobuf-c/protobuf-c-text.h b/protocols/Steam/src/protobuf-c/protobuf-c-text.h new file mode 100644 index 0000000000..bb3539737d --- /dev/null +++ b/protocols/Steam/src/protobuf-c/protobuf-c-text.h @@ -0,0 +1,213 @@ +#ifndef PROTOBUF_C_TEXT_H +#define PROTOBUF_C_TEXT_H + +/* + * \file + * Library header file. + * This is the header file for the text format protobuf routines. + * It contains declarations of all functions and data types exported by + * the library. + * + * \author Kevin Lyda <kevin@ie.suberic.net> + * \date March 2014 + * + */ + +/** \mainpage + * + * \section description Description + * + * Google protobufs are an efficient way to serialise and deserialise + * data to send across the wire or to store on disk. The Google compiler + * and related libraries provide implementations for C++, Java and Python. + * A very simple message definition language is used to generate parsers + * and generators for this binary format. + * + * The Protobuf compiler and library for C provide access to this + * technology from within C code. + * + * Besides the efficient binary protobuf format there is also a text mode + * format which is accessible to code generated by the Google protobuf + * compiler. While the text format has limitations - namely that it lacks + * some of the back/forwards-compatibility features of the binary format - + * it can be a useful debugging tool and a strict but human readable config + * file format. + * + * The C protobuf implementation is very minimal and lacks this feature. + * This library supplements \c libprotobuf-c and provides functions to + * generate and consume text format protobuf. They will work fine with + * any \c ProtobufCMessage subtype generated by the \c protoc-c + * compiler. + * + * \sa + * - Google Protobufs: https://code.google.com/p/protobuf/ + * - Protobuf docs: + * https://developers.google.com/protocol-buffers/docs/overview + * - Notes on protobuf compatibility: + * https://developers.google.com/protocol-buffers/docs/proto#updating + * - Protobuf for C code: https://github.com/protobuf-c/protobuf-c + * - Protobuf for C docs: + * https://github.com/protobuf-c/protobuf-c/wiki + * - Protobuf for C RPC library code: + * https://github.com/protobuf-c/protobuf-c-rpc + * - Protobuf for C text format code: + * https://github.com/protobuf-c/protobuf-c-text + * - Protobuf for C text format + * <a href=coverage/index.html>test coverage</a> + * + * \section example Examples + * + * Both examples use this \c .proto definition: + * \verbatim +message Ponycopter { + optional string hair_colour = 1; + optional uint32 rotors = 2; + optional uint32 awesomeness = 3; +} +\endverbatim + * + * \b Generating + * + * \verbatim +#include <protobuf-c/protobuf-c.h> +#include "ponycopter.pb-c.h" + +int main(int argc, char *argv[]) { + int len; + char *pc_bin, *pc_text; + Ponycopter *pc; + + pc_bin = read_a_blob(argv[1], &len); + pc = ponycopter__unpack(NULL, len, pc_bin); + pc_text = protobuf_c_text_to_string((ProtobufCMessage *)pc, NULL); + printf("Ponycopter: %s\n", pc_text); +} +\endverbatim + * + * \b Parsing + * + * \verbatim +#include <protobuf-c/protobuf-c.h> +#include "ponycopter.pb-c.h" + +int main(int argc, char *argv[]) { + ProtobufCTextError tf_res; + Ponycopter *pc; + + pc = (Ponycopter *)protobuf_c_text_from_file( + &ponycopter__descriptor, argv[1], &tf_res, NULL); +} +\endverbatim + */ + +#include <stdio.h> /* for the FILE * data type. */ +#include "protobuf-c.h" + +/** \defgroup api Public API for text format protobufs + * + * These functions supplement the generated code from \c protoc-c to + * allow you to import and export \c ProtobufCMessage structures + * from/to the protobuf text mode serialisation. + * + * These will work with any code generated from \c protoc-c. + * @{ + */ + +/** Structure for reporting API errors. + * + * Provides feedback on the success of an API call. Generally if an + * API call fails it will return \c NULL. More detail on why it failed + * can be found in the parameter with this type. + */ +typedef struct _ProtobufCTextError { + int *error; /**< Error code. 0 for success, >0 for failure. */ + char *error_txt; /**< String with error message. */ + int complete; /**< Reports whether the message is complete + (if supported): + - -1: Required field check wasn't performed - this + happens if your libprotobuf-c is too old. + - 0: The message was incomplete. + - >0: Message has all required fields set. */ +} ProtobufCTextError; + +/** Convert a \c ProtobufCMessage to a string. + * + * Given a \c ProtobufCMessage serialise it as a text format protobuf. + * + * \param[in] m The \c ProtobufCMessage to be serialised. + * \param[in] allocator This is the same \c ProtobufCAllocator type used + * by the \c libprotobuf-c library. You can set it + * to \c NULL to accept \c protobuf_c_default_allocator - + * the default allocator. + * \return The string with the text format serialised \c ProtobufCMessage. + * On failure it will return \c NULL. On success, the resulting value + * be freed by you with the \c allocator you provided. If you didn't + * provide an allocator technically you should do: + * \code + * protobuf_c_default_allocator.free( + * protobuf_c_default_allocator.allocator_data, retval); + * \endcode + * Though technically \c free(retval); is probably sufficient. + */ +extern char *protobuf_c_text_to_string(ProtobufCMessage *m, + ProtobufCAllocator *allocator); + +/** Import a text format protobuf from a string into a \c ProtobufCMessage. + * + * Given a string containing a text format protobuf, parse it and return + * the corresponding \c ProtobufCMessage struct. On failure, \c NULL is + * returned and \c result is updated with why. + * + * The resulting \c ProtobufCMessage should be freed with + * \c protobuf_c_message_free_unpacked() or the generated + * \c ..._free_upacked() function. Either is fine, but that's how the + * memory should be freed. + * + * \param[in] descriptor The descriptor from the generated code. + * \param[in] msg The string containing the text format protobuf. + * \param[out] result This structure contains information on any error + * that halted processing. + * \param[in] allocator This is the same \c ProtobufCAllocator type used + * by the \c libprotobuf-c library. You can set it + * to \c NULL to accept \c protobuf_c_default_allocator - + * the default allocator. + * \return The resulting \c ProtobufCMessage . It returns \c NULL on error. + * Check \c result->complete to make sure the message is valid. + */ +extern ProtobufCMessage *protobuf_c_text_from_string( + const ProtobufCMessageDescriptor *descriptor, + char *msg, + ProtobufCTextError *result, + ProtobufCAllocator *allocator); + +/** Import a text format protobuf from a \c FILE into a \c ProtobufCMessage. + * + * Given a \c FILE containing a text format protobuf, parse it and return + * the corresponding \c ProtobufCMessage struct. On failure, \c NULL is + * returned and \c result is updated with why. + * + * The resulting \c ProtobufCMessage should be freed with + * \c protobuf_c_message_free_unpacked() or the generated + * \c ..._free_upacked() function. Either is fine, but that's how the + * memory should be freed. + * + * \param[in] descriptor The descriptor from the generated code. + * \param[in] msg_file The \c FILE containing the text format protobuf. + * \param[out] result This structure contains information on any error + * that halted processing. + * \param[in] allocator This is the same \c ProtobufCAllocator type used + * by the \c libprotobuf-c library. You can set it + * to \c NULL to accept \c protobuf_c_default_allocator - + * the default allocator. + * \return The resulting \c ProtobufCMessage . It returns \c NULL on error. + * Check \c result->complete to make sure the message is valid. + */ +extern ProtobufCMessage *protobuf_c_text_from_file( + const ProtobufCMessageDescriptor *descriptor, + FILE *msg_file, + ProtobufCTextError *result, + ProtobufCAllocator *allocator); + +/** @} */ /* End of API group. */ + +#endif /* PROTOBUF_C_TEXT_H */ diff --git a/protocols/Steam/src/stdafx.h b/protocols/Steam/src/stdafx.h index 2fd47d20f1..11cdbe7e49 100644 --- a/protocols/Steam/src/stdafx.h +++ b/protocols/Steam/src/stdafx.h @@ -44,6 +44,11 @@ #include "protobuf-c/steammessages_friendmessages.steamclient.pb-c.h"
#include "proto.h"
+extern "C"
+{
+ #include "protobuf-c/protobuf-c-text.h"
+}
+
#define MODULE "Steam"
#define DB_KEY_LASTMSGTS "LastMessageTS"
diff --git a/protocols/Steam/src/steam_ws.cpp b/protocols/Steam/src/steam_ws.cpp index 7c7c6f32c1..f22587eca4 100644 --- a/protocols/Steam/src/steam_ws.cpp +++ b/protocols/Steam/src/steam_ws.cpp @@ -139,7 +139,7 @@ void CSteamProto::ProcessMessage(const uint8_t *buf, size_t cbLen) else if (bIsProto) { uint32_t hdrLen = *(uint32_t *)buf; buf += sizeof(uint32_t); cbLen -= sizeof(uint32_t); proto::MsgProtoBufHeader tmpHeader(buf, hdrLen); - if (tmpHeader == nullptr) { + if (tmpHeader == nullptr) { debugLogA("Unable to decode message header, exiting"); return; } |