dong_dl пре 1 година
родитељ
комит
28f75eb558

+ 24 - 11
inc/proto/MqttLog.h

@@ -1,16 +1,29 @@
 #pragma once
 
-enum MQTT_LOG_LEVEL {
-	MQTT_LOG_TRACE,
-	MQTT_LOG_DEBUG,
-	MQTT_LOG_INFO,
-	MQTT_LOG_WARN,
-	MQTT_LOG_ERROR,
+enum LOG_LEVEL
+{
+    LOG_TRACE,
+    LOG_DEBUG,
+    LOG_INFO,
+    LOG_WARN,
+    LOG_ERROR,
 };
 
-MQTTAPI void MqttLog(MQTT_LOG_LEVEL level, const char* msg, ...);
-MQTTAPI void MqttLogHex(MQTT_LOG_LEVEL level, std::string& str);
+enum LOG_TYPE
+{
+    LOG_TYPE_NONE = 0,
+    LOG_TYPE_MQTT = 1,
+    LOG_TYPE_DATA = 2,
+    LOG_TYPE_FUNC = 4,
+    LOG_TYPE_ALL  = 0xffff
+};
+
+MQTTAPI void MqttSetLogType(LOG_TYPE type);
+MQTTAPI void MqttSetLogLevel(LOG_LEVEL level);
+
+MQTTAPI void MqttLog(LOG_LEVEL level, LOG_TYPE type, const char *msg, ...);
+MQTTAPI void MqttLogHex(LOG_LEVEL level, LOG_TYPE type, std::string &str);
 
-#define FUNC_ENTRY			//MqttLog(MQTT_LOG_TRACE, "entry function: %s(%d)", __FUNCTION__, __LINE__)
-#define FUNC_EXIT			//MqttLog(MQTT_LOG_TRACE, "leave function: %s", __FUNCTION__)
-#define FUNC_EXIT_RC(rc)	//MqttLog(MQTT_LOG_TRACE, "leave function: %s, ret: %d", __FUNCTION__, rc)
+#define FUNC_ENTRY       //MqttLog(MQTT_LOG_TRACE, "entry function: %s(%d)", __FUNCTION__, __LINE__)
+#define FUNC_EXIT        //MqttLog(MQTT_LOG_TRACE, "leave function: %s", __FUNCTION__)
+#define FUNC_EXIT_RC(rc) //MqttLog(MQTT_LOG_TRACE, "leave function: %s, ret: %d", __FUNCTION__, rc)

+ 87 - 70
inc/proto/ProtoParser.h

@@ -20,6 +20,12 @@ struct TopicCallback
     std::function<void(int, std::string)> cb;
 };
 
+struct PublishInfo
+{
+    std::string topic;
+    std::string payload;
+};
+
 typedef void (*parserCallback)(const char *topic, const char *json, void *userData);
 
 class ProtoParserPrivate;
@@ -43,7 +49,7 @@ public:
     std::string routeRequest(std::string request, std::string payload);
     std::string routeResponse(std::string response);
 
-    std::string publish(std::string topic, std::string payload, uint32_t *msgId = nullptr);
+    std::string publish(std::string topic, std::string payload, uint32_t &msgId);
 
 #if !defined USE_WASM
     void test();
@@ -53,39 +59,39 @@ public:
     std::string connectPack(std::string userName);
     std::string disconnectPack();
     std::string pingPack();
-    std::string pullFriendPack(std::string requestJson);
-    std::string pullFriendRequestPack(std::string requestJson);
-    std::string addFriendPack(std::string requestJson);
-    std::string addGroupMemberPack(std::string requestJson);
-    std::string createGroupPack(std::string requestJson);
-    std::string deleteFriendPack(std::string requestJson);
-    std::string dismissGroupPack(std::string requestJson);
-    std::string getGroupInfoPack(std::string requestJson);
-    std::string getGroupMemberPack(std::string requestJson);
-    std::string getUserInfoPack(std::string requestJson);
-    std::string getUserSettingPack(std::string requestJson);
-    std::string handleFriendRequestPack(std::string requestJson);
-    std::string loadRemoteMessagesPack(std::string requestJson);
-    std::string modifyMyInfoPack(std::string requestJson);
-    std::string pullMessagePack(std::string requestJson);
-    std::string putUserSettingPack(std::string requestJson);
-    std::string quitGroupPack(std::string requestJson);
-    std::string recallMessagePack(std::string requestJson);
-    std::string syncFriendRequestUnreadPack(std::string requestJson);
-    std::string sendMessagePack(std::string requestJson);
-    std::string uploadMediaPack(std::string requestJson);
-    std::string userSearchPack(std::string requestJson);
+    std::string pullFriendPack(std::string requestJson, uint32_t &msgId);
+    std::string pullFriendRequestPack(std::string requestJson, uint32_t &msgId);
+    std::string addFriendPack(std::string requestJson, uint32_t &msgId);
+    std::string addGroupMemberPack(std::string requestJson, uint32_t &msgId);
+    std::string createGroupPack(std::string requestJson, uint32_t &msgId);
+    std::string deleteFriendPack(std::string requestJson, uint32_t &msgId);
+    std::string dismissGroupPack(std::string requestJson, uint32_t &msgId);
+    std::string getGroupInfoPack(std::string requestJson, uint32_t &msgId);
+    std::string getGroupMemberPack(std::string requestJson, uint32_t &msgId);
+    std::string getUserInfoPack(std::string requestJson, uint32_t &msgId);
+    std::string getUserSettingPack(std::string requestJson, uint32_t &msgId);
+    std::string handleFriendRequestPack(std::string requestJson, uint32_t &msgId);
+    std::string loadRemoteMessagesPack(std::string requestJson, uint32_t &msgId);
+    std::string modifyMyInfoPack(std::string requestJson, uint32_t &msgId);
+    std::string pullMessagePack(std::string requestJson, uint32_t &msgId);
+    std::string putUserSettingPack(std::string requestJson, uint32_t &msgId);
+    std::string quitGroupPack(std::string requestJson, uint32_t &msgId);
+    std::string recallMessagePack(std::string requestJson, uint32_t &msgId);
+    std::string syncFriendRequestUnreadPack(std::string requestJson, uint32_t &msgId);
+    std::string sendMessagePack(std::string requestJson, uint32_t &msgId);
+    std::string uploadMediaPack(std::string requestJson, uint32_t &msgId);
+    std::string userSearchPack(std::string requestJson, uint32_t &msgId);
     std::string newClientId();
-    std::string RriendRequestUnreadSyncPack(std::string requestJson);
-    std::string kickoffGroupMemberPack(std::string requestJson);
-    std::string modifyGroupInfoPack(std::string requestJson);
-    std::string modifyGroupAliasPack(std::string requestJson);
-    std::string modifyGroupMemberAliasPack(std::string requestJson);
-    std::string modifyGroupMemberExtraPack(std::string requestJson);
-    std::string setFriendAliasPack(std::string requestJson);
-    std::string transferGroupPack(std::string requestJson);
-    std::string setGroupManagerPack(std::string requestJson);
-    std::string clearMessagesPack(std::string requestJson);
+    std::string RriendRequestUnreadSyncPack(std::string requestJson, uint32_t &msgId);
+    std::string kickoffGroupMemberPack(std::string requestJson, uint32_t &msgId);
+    std::string modifyGroupInfoPack(std::string requestJson, uint32_t &msgId);
+    std::string modifyGroupAliasPack(std::string requestJson, uint32_t &msgId);
+    std::string modifyGroupMemberAliasPack(std::string requestJson, uint32_t &msgId);
+    std::string modifyGroupMemberExtraPack(std::string requestJson, uint32_t &msgId);
+    std::string setFriendAliasPack(std::string requestJson, uint32_t &msgId);
+    std::string transferGroupPack(std::string requestJson, uint32_t &msgId);
+    std::string setGroupManagerPack(std::string requestJson, uint32_t &msgId);
+    std::string clearMessagesPack(std::string requestJson, uint32_t &msgId);
 #pragma endregion
 
     int parse(std::vector<uint8_t> &data);
@@ -110,8 +116,8 @@ public:
     }
     std::string getKey(std::string key);
 
-    void addCallback(int msgId, std::function<void(int, std::string)> cb);
-    void removeCallback(int msgId);
+    void addCallback(uint32_t msgId, std::function<void(uint32_t, std::string)> cb);
+    void removeCallback(uint32_t msgId);
 
     bool     isConnected() const;
     uint64_t getMsgHead() const
@@ -184,9 +190,13 @@ public:
     std::string searchGroups(std::string keyword);
     std::string getConversationInfo(std::string request);
     std::string getMessages(std::string request);
+    std::string getMessage(uint64_t id);
     std::string getGroupMembers(std::string id);
     std::string searchConversation(std::string keyword, std::string types, std::string lines);
 
+    void setLogLevel(int level);
+    void setLogType(int type);
+
 #ifdef USE_WASM
     void setOnConnected(int ptr);
     void setOnDisconnected(int ptr);
@@ -211,14 +221,18 @@ public:
         return parse(vec);
     }
 
-#define WRAPPER(fn)                                                          \
-    uint32_t fn##Val(std::string requestJson)                                \
-    {                                                                        \
-        std::lock_guard<std::recursive_mutex> l(_sendLock);                  \
-        auto                                  ret   = fn##Pack(requestJson); \
-        auto                                  msgId = _msgId;                \
-        send(ret);                                                           \
-        return msgId;                                                        \
+#define WRAPPER(fn)                                                                 \
+    uint32_t fn##Val(std::string requestJson)                                       \
+    {                                                                               \
+        std::lock_guard<std::recursive_mutex> l(_sendLock);                         \
+        auto                                  msgId = _msgId;                       \
+        auto                                  ret   = fn##Pack(requestJson, msgId); \
+        if (ret.length() > 0)                                                       \
+        {                                                                           \
+            msgId = _msgId;                                                         \
+            send(ret);                                                              \
+        }                                                                           \
+        return msgId;                                                               \
     }
 
     WRAPPER(pullFriend);
@@ -262,10 +276,10 @@ protected:
     static EM_BOOL onWebSocketOpen(int eventType, const EmscriptenWebSocketOpenEvent *websocketEvent, void *userData);
     static EM_BOOL onWebSocketMessage(int eventType, const EmscriptenWebSocketMessageEvent *websocketEvent, void *userData);
 #endif
-    std::string dataEncrypt(std::string &str);
-    std::string dataDecrypt(std::string &str);
-    unsigned char parsePayload(std::string &payload, bool hasCode = false);
-    void        addMessages(std::list<Message> &msgs);
+    std::string   dataEncrypt(std::string &str);
+    std::string   dataDecrypt(std::string &str);
+    unsigned char parsePayload(std::string &payload, bool pub);
+    void          addMessages(std::list<Message> &msgs);
 
 private:
     bool     _connected    = false;
@@ -279,29 +293,29 @@ private:
     uint64_t _friendRqCurrent = 0;
     uint64_t _settingCurrent  = 0;
 
-    std::string                  _uid;
-    std::string                  _token;
-    std::string                  _secret;
-    std::string                  _clientId;
-    std::string                  _topic;
-    std::string                  _payload;
-    parserCallback               _callback       = nullptr;
-    onConnectedCallback          _onConnected    = nullptr;
-    onDisconnectedCallback       _onDisconnected = nullptr;
-    onMessageCallback            _onMessage      = nullptr;
-    void                        *_userData;
-    uint32_t                     _msgId     = 0;
-    uint32_t                     _respMsgId = 0;
-    uint64_t                     _timestamp = 0;
-    int                          _timeout   = 5000;
-    unsigned char                _rc        = 0;
-    std::mutex                   _msgIdLock;
-    std::map<int, std::string>   _topics;
-    std::mutex                   _callbackLock;
-    std::map<int, TopicCallback> _callbacks;
-    std::map<int, std::string>   _upui;
-    std::mutex                   _upuiLock;
-    ProtoParserPrivate          *p;
+    std::string                       _uid;
+    std::string                       _token;
+    std::string                       _secret;
+    std::string                       _clientId;
+    std::string                       _topic;
+    std::string                       _payload;
+    parserCallback                    _callback       = nullptr;
+    onConnectedCallback               _onConnected    = nullptr;
+    onDisconnectedCallback            _onDisconnected = nullptr;
+    onMessageCallback                 _onMessage      = nullptr;
+    void                             *_userData;
+    uint32_t                          _msgId     = 0;
+    uint32_t                          _respMsgId = 0;
+    uint64_t                          _timestamp = 0;
+    int                               _timeout   = 5000;
+    unsigned char                     _rc        = 0;
+    std::mutex                        _msgIdLock;
+    std::map<uint32_t, std::string>   _topics;
+    std::mutex                        _callbackLock;
+    std::map<uint32_t, TopicCallback> _callbacks;
+    std::map<uint32_t, PublishInfo>   _publishes;
+    std::mutex                        _publishLock;
+    ProtoParserPrivate               *p;
 #ifdef USE_WASM
     EMSCRIPTEN_WEBSOCKET_T _socket;
     std::string            _url;
@@ -377,11 +391,14 @@ EMSCRIPTEN_BINDINGS(Proto)
         .function("modifyGroupMemberExtraAsync", &ProtoParser::modifyGroupMemberExtraVal)
         .function("getConversationInfo", &ProtoParser::getConversationInfo)
         .function("getMessages", &ProtoParser::getMessages)
+        .function("getMessage", &ProtoParser::getMessage)
         .function("getGroupMembers", &ProtoParser::getGroupMembers)
         .function("searchConversation", &ProtoParser::searchConversation)
         .function("setOnConnected", &ProtoParser::setOnConnected)
         .function("setOnMessage", &ProtoParser::setOnMessage)
         .function("setOnDisconnected", &ProtoParser::setOnDisconnected)
+        .function("setLogLevel", &ProtoParser::setLogLevel)
+        .function("setLogType", &ProtoParser::setLogType)
 
         .property("timeout", &ProtoParser::getTimeout, &ProtoParser::setTimeout)
         .property("secret", &ProtoParser::getSecret)

+ 2 - 2
src/proto/Crypt.cpp

@@ -196,14 +196,14 @@ int encode(uint8_t *str, char *outStr)
     int     n = aesEncrypt(str, strlen((char *)str), nullptr, tmp);
     if (n <= 0)
     {
-        MqttLog(MQTT_LOG_ERROR, "aesEncrypt return: %d", n);
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "aesEncrypt return: %d", n);
         return n;
     }
     auto len = base64EncodeLength(tmp, n);
     n        = base64Encode(outStr, len, tmp, n);
     if (n <= 0)
     {
-        MqttLog(MQTT_LOG_ERROR, "base64Encode return: %d", n);
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "base64Encode return: %d", n);
         return n;
     }
     outStr[n] = 0;

+ 67 - 41
src/proto/MqttLog.cpp

@@ -2,55 +2,81 @@
 #include <proto/MqttLog.h>
 #include <stdarg.h>
 
-void MqttLog(MQTT_LOG_LEVEL level, const char* msg, ...)
+LOG_LEVEL g_logLevel = LOG_WARN;
+LOG_TYPE  g_logType  = LOG_TYPE_ALL;
+
+void MqttSetLogType(LOG_TYPE type)
+{
+    g_logType = type;
+}
+void MqttSetLogLevel(LOG_LEVEL level)
+{
+    g_logLevel = level;
+}
+
+void MqttLog(LOG_LEVEL level, LOG_TYPE type, const char *msg, ...)
 {
-	va_list argList;
-	va_start(argList, msg);
-	const int legacyBufSize = 1024*1024;
-	char* szBuffer = new char[legacyBufSize + 1];
-	int length = vsprintf(szBuffer, msg, argList);
+    if (level != LOG_ERROR)
+    {
+        if (level < g_logLevel)
+            return;
+        if ((type & g_logType) == 0)
+            return;
+    }
+    va_list argList;
+    va_start(argList, msg);
+    const int legacyBufSize = 1024 * 1024;
+    char     *szBuffer      = new char[legacyBufSize + 1];
+    int       length        = vsprintf(szBuffer, msg, argList);
 #ifdef USE_WASM
-	auto l = 0;
-	switch (level)
-	{
-	case MQTT_LOG_TRACE:
-		break;
-	case MQTT_LOG_DEBUG:
-		l = EM_LOG_DEBUG;
-		break;
-	case MQTT_LOG_INFO:
-		l = EM_LOG_INFO;
-		break;
-	case MQTT_LOG_WARN:
-		l = EM_LOG_WARN;
-		break;
-	case MQTT_LOG_ERROR:
-		l = EM_LOG_ERROR;
-		break;
-	}
-	// EM_LOG_C_STACK
-	emscripten_log(l | EM_LOG_CONSOLE, szBuffer);
+    auto l = 0;
+    switch (level)
+    {
+    case LOG_TRACE:
+        break;
+    case LOG_DEBUG:
+        l = EM_LOG_DEBUG;
+        break;
+    case LOG_INFO:
+        l = EM_LOG_INFO;
+        break;
+    case LOG_WARN:
+        l = EM_LOG_WARN;
+        break;
+    case LOG_ERROR:
+        l = EM_LOG_ERROR;
+        break;
+    }
+    // EM_LOG_C_STACK
+    emscripten_log(l | EM_LOG_CONSOLE, szBuffer);
 
 #else
-	printf("%s\n", szBuffer);
+    printf("%s\n", szBuffer);
 #endif
-	va_end(argList);
+    va_end(argList);
     delete[] szBuffer;
 }
 
-void MqttLogHex(MQTT_LOG_LEVEL level, std::string& str)
+void MqttLogHex(LOG_LEVEL level, LOG_TYPE type, std::string &str)
 {
-	const int legacyBufSize = 1024*1024;
-	char* szBuffer = new char[legacyBufSize + 1];
-	szBuffer[0] = 0;
-	for (int i = 0; i < 100 && i < str.length(); i++)
-	{
-		char tmp[100];
-		sprintf(tmp, "%02X ", (unsigned char)str[i]);
-		strcat(szBuffer, tmp);
-		if ((i % 16) == 15)
-			strcat(szBuffer, "\r\n");
-	}
-	MqttLog(level, szBuffer);
+    if (level != LOG_ERROR)
+    {
+        if (level < g_logLevel)
+            return;
+        if ((type & g_logType) == 0)
+            return;
+    }
+    const int legacyBufSize = 1024 * 1024;
+    char     *szBuffer      = new char[legacyBufSize + 1];
+    szBuffer[0]             = 0;
+    for (int i = 0; i < 100 && i < str.length(); i++)
+    {
+        char tmp[100];
+        sprintf(tmp, "%02X ", (unsigned char)str[i]);
+        strcat(szBuffer, tmp);
+        if ((i % 16) == 15)
+            strcat(szBuffer, "\r\n");
+    }
+    MqttLog(level, type, szBuffer);
     delete[] szBuffer;
 }

+ 194 - 194
src/proto/MqttPacket.cpp

@@ -1,225 +1,225 @@
 #include "pch.h"
 #include <proto/MqttPacket.h>
 
-int mqttReadInt(const char** pptr)
+int mqttReadInt(const char **pptr)
 {
-	const char* ptr = *pptr;
-	int len = 256 * ((unsigned char)(*ptr)) + (unsigned char)(*(ptr + 1));
-	*pptr += 2;
-	return len;
+    const char *ptr = *pptr;
+    int         len = 256 * ((unsigned char)(*ptr)) + (unsigned char)(*(ptr + 1));
+    *pptr += 2;
+    return len;
 }
 
-char* mqttReadUTFlen(const char** pptr, const char* enddata, int* len)
+char *mqttReadUTFlen(const char **pptr, const char *enddata, int *len)
 {
-	char* string = NULL;
+    char *string = NULL;
 
-	FUNC_ENTRY;
-	if (enddata - (*pptr) > 1) /* enough length to read the integer? */
-	{
-		*len = mqttReadInt(pptr);
-		if (&(*pptr)[*len] <= enddata)
-		{
-			if ((string = (char*)malloc(*len + 1)) == NULL)
-				goto exit;
-			memcpy(string, *pptr, *len);
-			string[*len] = '\0';
-			*pptr += *len;
-		}
-	}
+    FUNC_ENTRY;
+    if (enddata - (*pptr) > 1) /* enough length to read the integer? */
+    {
+        *len = mqttReadInt(pptr);
+        if (&(*pptr)[*len] <= enddata)
+        {
+            if ((string = (char *)malloc(*len + 1)) == NULL)
+                goto exit;
+            memcpy(string, *pptr, *len);
+            string[*len] = '\0';
+            *pptr += *len;
+        }
+    }
 exit:
-	FUNC_EXIT;
-	return string;
+    FUNC_EXIT;
+    return string;
 }
 
-char* mqttReadUTF(const char** pptr, const char* enddata)
+char *mqttReadUTF(const char **pptr, const char *enddata)
 {
-	int len;
-	return mqttReadUTFlen(pptr, enddata, &len);
+    int len;
+    return mqttReadUTFlen(pptr, enddata, &len);
 }
 
-unsigned char mqttReadChar(const char** pptr)
+unsigned char mqttReadChar(const char **pptr)
 {
-	unsigned char c = **pptr;
-	(*pptr)++;
-	return c;
+    unsigned char c = **pptr;
+    (*pptr)++;
+    return c;
 }
 
-void mqttReadHeader(const char** pptr, MqttHeader& header, size_t* value)
+void mqttReadHeader(const char **pptr, MqttHeader &header, size_t *value)
 {
-	unsigned char h = **pptr;
-	memcpy(&header, &h, 1);
-	(*pptr)++;
+    unsigned char h = **pptr;
+    memcpy(&header, &h, 1);
+    (*pptr)++;
 
-	char c;
-	int multiplier = 1;
-	int len = 0;
+    char c;
+    int  multiplier = 1;
+    int  len        = 0;
 #define MAX_NO_OF_REMAINING_LENGTH_BYTES 4
 
-	FUNC_ENTRY;
-	*value = 0;
-	do
-	{
-		if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
-		{
-			break;
-		}
-		c = **pptr;
-		(*pptr)++;
-		*value += (c & 127) * multiplier;
-		multiplier *= 128;
-	} while ((c & 128) != 0);
+    FUNC_ENTRY;
+    *value = 0;
+    do
+    {
+        if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
+        {
+            break;
+        }
+        c = **pptr;
+        (*pptr)++;
+        *value += (c & 127) * multiplier;
+        multiplier *= 128;
+    } while ((c & 128) != 0);
 }
 
-void mqttWriteChar(std::string& buffer, char c)
+void mqttWriteChar(std::string &buffer, char c)
 {
-	buffer.append(&c, 1);
+    buffer.append(&c, 1);
 }
 
-void mqttWriteChar(char** pptr, char c)
+void mqttWriteChar(char **pptr, char c)
 {
-	**pptr = c;
-	(*pptr)++;
+    **pptr = c;
+    (*pptr)++;
 }
 
-void mqttWriteInt(std::string& buffer, int anInt)
+void mqttWriteInt(std::string &buffer, int anInt)
 {
-	char ch[2];
-	ch[0] = (char)(anInt / 256);
-	ch[1] = (char)(anInt % 256);
-	buffer.append(ch, 2);
+    char ch[2];
+    ch[0] = (char)(anInt / 256);
+    ch[1] = (char)(anInt % 256);
+    buffer.append(ch, 2);
 }
 
-void mqttWriteInt(char** pptr, int anInt)
+void mqttWriteInt(char **pptr, int anInt)
 {
-	**pptr = (char)(anInt / 256);
-	(*pptr)++;
-	**pptr = (char)(anInt % 256);
-	(*pptr)++;
+    **pptr = (char)(anInt / 256);
+    (*pptr)++;
+    **pptr = (char)(anInt % 256);
+    (*pptr)++;
 }
 
-void mqttWriteUTF(char** pptr, const char* string)
+void mqttWriteUTF(char **pptr, const char *string)
 {
-	size_t len = strlen(string);
-	mqttWriteInt(pptr, (int)len);
-	memcpy(*pptr, string, len);
-	*pptr += len;
+    size_t len = strlen(string);
+    mqttWriteInt(pptr, (int)len);
+    memcpy(*pptr, string, len);
+    *pptr += len;
 }
 
-void mqttWriteUTF(std::string& buffer, const char* string)
+void mqttWriteUTF(std::string &buffer, const char *string)
 {
-	size_t len = strlen(string);
-	mqttWriteInt(buffer, (int)len);
-	buffer.append(string, len);
+    size_t len = strlen(string);
+    mqttWriteInt(buffer, (int)len);
+    buffer.append(string, len);
 }
 
-void mqttWriteData(char** pptr, const void* data, int datalen)
+void mqttWriteData(char **pptr, const void *data, int datalen)
 {
-	mqttWriteInt(pptr, datalen);
-	memcpy(*pptr, data, datalen);
-	*pptr += datalen;
+    mqttWriteInt(pptr, datalen);
+    memcpy(*pptr, data, datalen);
+    *pptr += datalen;
 }
 
-void mqttWriteDataNoLen(char** pptr, const void* data, int datalen)
+void mqttWriteDataNoLen(char **pptr, const void *data, int datalen)
 {
-	memcpy(*pptr, data, datalen);
-	*pptr += datalen;
+    memcpy(*pptr, data, datalen);
+    *pptr += datalen;
 }
 
-void mqttWriteData(std::string& buffer, const void* data, int datalen)
+void mqttWriteData(std::string &buffer, const void *data, int datalen)
 {
-	mqttWriteInt(buffer, datalen);
-	buffer.append((const char*)data, datalen);
+    mqttWriteInt(buffer, datalen);
+    buffer.append((const char *)data, datalen);
 }
-void mqttWriteDataNoLen(std::string& buffer, const void* data, int datalen)
+void mqttWriteDataNoLen(std::string &buffer, const void *data, int datalen)
 {
-	buffer.append((const char*)data, datalen);
+    buffer.append((const char *)data, datalen);
 }
 
-void mqttWriteHeader(std::string& buffer, MqttHeader& header, size_t len)
+void mqttWriteHeader(std::string &buffer, MqttHeader &header, size_t len)
 {
-	mqttWriteChar(buffer, header.byte);
-	do
-	{
-		char d = len % 128;
-		len /= 128;
-		/* if there are more digits to encode, set the top bit of this digit */
-		if (len > 0)
-			d |= 0x80;
-		buffer.append(&d, 1);
-	} while (len > 0);
+    mqttWriteChar(buffer, header.byte);
+    do
+    {
+        char d = len % 128;
+        len /= 128;
+        /* if there are more digits to encode, set the top bit of this digit */
+        if (len > 0)
+            d |= 0x80;
+        buffer.append(&d, 1);
+    } while (len > 0);
 }
 
-int mqttToBuffer(MqttConnectPacket* packet, std::string& buffer)
+int mqttToBuffer(MqttConnectPacket *packet, std::string &buffer)
 {
-	int rc = 0;
-	FUNC_ENTRY;
-	size_t len = 10;
-	if (packet->version >= MqttVersion_5)
-		len++;
-	len += packet->clientID.length() + 2;
-	if (packet->flags.bits.username)
-		len += packet->username.length() + 2;
-	if (packet->flags.bits.password)
-		len += packet->password.length() + 2;
-	if (packet->payload.length() > 0)
-		len += packet->payload.length() + 2;
+    int rc = 0;
+    FUNC_ENTRY;
+    size_t len = 10;
+    if (packet->version >= MqttVersion_5)
+        len++;
+    len += packet->clientID.length() + 2;
+    if (packet->flags.bits.username)
+        len += packet->username.length() + 2;
+    if (packet->flags.bits.password)
+        len += packet->password.length() + 2;
+    if (packet->payload.length() > 0)
+        len += packet->payload.length() + 2;
 
-	mqttWriteHeader(buffer, packet->header, len);
+    mqttWriteHeader(buffer, packet->header, len);
 
-	mqttWriteUTF(buffer, "MQTT");
-	mqttWriteChar(buffer, packet->version);
-	mqttWriteChar(buffer, packet->flags.all);
-	mqttWriteInt(buffer, packet->keepAliveTimer);
-	if (packet->version >= MqttVersion_5)
-		mqttWriteChar(buffer, 0);
-	mqttWriteUTF(buffer, packet->clientID.c_str());
-	/*if (client->will)
+    mqttWriteUTF(buffer, "MQTT");
+    mqttWriteChar(buffer, packet->version);
+    mqttWriteChar(buffer, packet->flags.all);
+    mqttWriteInt(buffer, packet->keepAliveTimer);
+    if (packet->version >= MqttVersion_5)
+        mqttWriteChar(buffer, 0);
+    mqttWriteUTF(buffer, packet->clientID.c_str());
+    /*if (client->will)
 	{
 		if (packet->version >= MqttVersion_5)
 			MQTTProperties_write(&ptr, willProperties);
 		writeUTF(&ptr, client->will->topic);
 		writeData(&ptr, client->will->payload, client->will->payloadlen);
 	}*/
-	if (packet->flags.bits.username)
-		mqttWriteUTF(buffer, packet->username.c_str());
-	if (packet->flags.bits.password)
-		mqttWriteData(buffer, packet->password.c_str(), packet->password.length());
-	if (packet->payload.length() > 0)
-		mqttWriteData(buffer, packet->payload.c_str(), packet->payload.length());
+    if (packet->flags.bits.username)
+        mqttWriteUTF(buffer, packet->username.c_str());
+    if (packet->flags.bits.password)
+        mqttWriteData(buffer, packet->password.c_str(), packet->password.length());
+    if (packet->payload.length() > 0)
+        mqttWriteData(buffer, packet->payload.c_str(), packet->payload.length());
 clean:
-	FUNC_EXIT_RC(rc);
-	return rc;
+    FUNC_EXIT_RC(rc);
+    return rc;
 }
 
-int mqttToBuffer(MqttPublishPacket* packet, std::string& buffer)
+int mqttToBuffer(MqttPublishPacket *packet, std::string &buffer)
 {
-	int rc = 0;
-	FUNC_ENTRY;
+    int rc = 0;
+    FUNC_ENTRY;
 
-	size_t len = 5;
-	len += packet->payload.length() + packet->topic.length();
-	mqttWriteHeader(buffer, packet->header, len);
-	mqttWriteUTF(buffer, packet->topic.c_str());
-	mqttWriteInt(buffer, packet->msgId);
-	mqttWriteChar(buffer, 0);
-	if (packet->payload.length() > 0)
-		mqttWriteDataNoLen(buffer, packet->payload.c_str(), packet->payload.length());
+    size_t len = 5;
+    len += packet->payload.length() + packet->topic.length();
+    mqttWriteHeader(buffer, packet->header, len);
+    mqttWriteUTF(buffer, packet->topic.c_str());
+    mqttWriteInt(buffer, packet->msgId);
+    mqttWriteChar(buffer, 0);
+    if (packet->payload.length() > 0)
+        mqttWriteDataNoLen(buffer, packet->payload.c_str(), packet->payload.length());
 clean:
-	FUNC_EXIT_RC(rc);
-	return rc;
+    FUNC_EXIT_RC(rc);
+    return rc;
 }
 
-int mqttFromBuffer(MqttConnAckPacket* packet, std::vector<uint8_t>& buffer)
+int mqttFromBuffer(MqttConnAckPacket *packet, std::vector<uint8_t> &buffer)
 {
-	int rc = 0;
-	FUNC_ENTRY;
-	const char* curdata = (const char*)&buffer[0];
-	const char* enddata = (const char*)&buffer[buffer.size() - 1];
-	size_t len = 0;
-	mqttReadHeader(&curdata, packet->header, &len);
-	packet->flags.all = mqttReadChar(&curdata); /* connect flags */
-	packet->rc = mqttReadChar(&curdata); /* reason code */
-	/*if (MQTTVersion >= MQTTVERSION_5 && datalen > 2)
+    int rc = 0;
+    FUNC_ENTRY;
+    const char *curdata = (const char *)&buffer[0];
+    const char *enddata = (const char *)&buffer[buffer.size() - 1];
+    size_t      len     = 0;
+    mqttReadHeader(&curdata, packet->header, &len);
+    packet->flags.all = mqttReadChar(&curdata); /* connect flags */
+    packet->rc        = mqttReadChar(&curdata); /* reason code */
+    /*if (MQTTVersion >= MQTTVERSION_5 && datalen > 2)
 	{
 		MQTTProperties props = MQTTProperties_initializer;
 		pack->properties = props;
@@ -233,61 +233,61 @@ int mqttFromBuffer(MqttConnAckPacket* packet, std::vector<uint8_t>& buffer)
 			goto exit;
 		}
 	}*/
-	len = mqttReadChar(&curdata);
-	curdata = curdata + len;
-	if (curdata != enddata)
-	{
-		packet->payload.append(curdata, enddata - curdata + 1);
-	}
+    len     = mqttReadChar(&curdata);
+    curdata = curdata + len;
+    if (curdata != enddata)
+    {
+        packet->payload.append(curdata, enddata - curdata + 1);
+    }
 clean:
-	FUNC_EXIT_RC(rc);
-	return rc;
+    FUNC_EXIT_RC(rc);
+    return rc;
 }
 
-int mqttFromBuffer(MqttPubAckPacket* packet, std::vector<uint8_t>& buffer)
+int mqttFromBuffer(MqttPubAckPacket *packet, std::vector<uint8_t> &buffer)
 {
-	int rc = 0;
-	FUNC_ENTRY;
-	const char* curdata = (const char*)&buffer[0];
-	const char* enddata = (const char*)&buffer[buffer.size() - 1];
-	size_t len = 0;
-	mqttReadHeader(&curdata, packet->header, &len);
-	packet->msgId = mqttReadInt(&curdata);
-	packet->rc = mqttReadChar(&curdata);
-	mqttReadChar(&curdata);
-	if (curdata != enddata)
-	{
-		packet->payload.append(curdata, enddata - curdata + 1);
-	}
+    int rc = 0;
+    FUNC_ENTRY;
+    const char *curdata = (const char *)&buffer[0];
+    const char *enddata = (const char *)&buffer[buffer.size() - 1];
+    size_t      len     = 0;
+    mqttReadHeader(&curdata, packet->header, &len);
+    packet->msgId = mqttReadInt(&curdata);
+    packet->rc    = mqttReadChar(&curdata);
+    mqttReadChar(&curdata);
+    if (curdata != enddata)
+    {
+        packet->payload.append(curdata, enddata - curdata + 1);
+    }
 clean:
-	FUNC_EXIT_RC(rc);
-	return rc;
+    FUNC_EXIT_RC(rc);
+    return rc;
 }
 
-int mqttFromBuffer(MqttPublishPacket* packet, std::vector<uint8_t>& buffer)
+int mqttFromBuffer(MqttPublishPacket *packet, std::vector<uint8_t> &buffer)
 {
-	int rc = 0;
-	FUNC_ENTRY;
-	const char* curdata = (const char*)&buffer[0];
-	const char* enddata = (const char*)&buffer[buffer.size() - 1];
-	size_t len = 0;
-	mqttReadHeader(&curdata, packet->header, &len);
+    int rc = 0;
+    FUNC_ENTRY;
+    const char *curdata = (const char *)&buffer[0];
+    const char *enddata = (const char *)&buffer[buffer.size() - 1];
+    size_t      len     = 0;
+    mqttReadHeader(&curdata, packet->header, &len);
 
-	auto topic = mqttReadUTF(&curdata, enddata);
-	if (topic != nullptr)
-	{
-		packet->topic = topic;
-		free(topic);
-	}
+    auto topic = mqttReadUTF(&curdata, enddata);
+    if (topic != nullptr)
+    {
+        packet->topic = topic;
+        free(topic);
+    }
 
-	packet->msgId = mqttReadInt(&curdata);
-	mqttReadChar(&curdata);
+    packet->msgId = 0; //mqttReadInt(&curdata);
+    mqttReadChar(&curdata);
 
-	if (curdata != enddata)
-	{
-		packet->payload.append(curdata, enddata - curdata + 1);
-	}
+    if (curdata != enddata)
+    {
+        packet->payload.append(curdata, enddata - curdata + 1);
+    }
 clean:
-	FUNC_EXIT_RC(rc);
-	return rc;
+    FUNC_EXIT_RC(rc);
+    return rc;
 }

Разлика између датотеке није приказан због своје велике величине
+ 255 - 160
src/proto/ProtoParser.cpp


+ 63 - 1
src/proto/ProtoParserPrivate.cpp

@@ -182,7 +182,7 @@ int ProtoParserPrivate::getUserSetting(int scope, const char *type, std::functio
 #endif
 }
 
-int ProtoParserPrivate::getFriend(const char *uid, std::function<bool(const Friend &item)> cb)
+int ProtoParserPrivate::getFriend(std::function<bool(const Friend &item)> cb)
 {
 #ifdef USE_ALL_SQLITE3
     // TODO:
@@ -196,6 +196,25 @@ int ProtoParserPrivate::getFriend(const char *uid, std::function<bool(const Frie
 #endif
 }
 
+int ProtoParserPrivate::getFriend(const char *uid, std::function<bool(const Friend &item)> cb)
+{
+#ifdef USE_ALL_SQLITE3
+    // TODO:
+#else
+    for (const auto it : _friends)
+    {
+        if (uid == it.uid())
+        {
+            if (!cb(it))
+            {
+                break;
+            }
+        }
+    }
+    return 0;
+#endif
+}
+
 int ProtoParserPrivate::getUser(const char *uid, const char *gid, std::function<bool(const User &item)> cb)
 {
 #ifdef USE_ALL_SQLITE3
@@ -245,6 +264,8 @@ int ProtoParserPrivate::getGroupMembers(const char *id, std::function<bool(const
 
 void ProtoParserPrivate::sendMessage(Message &msg, uint32_t msgId)
 {
+    if (msgId == 0)
+        return;
 #ifdef USE_SQLITE3
 // TODO:
 #else
@@ -262,6 +283,22 @@ void ProtoParserPrivate::sendMessage(Message &msg, uint32_t msgId)
 #endif
 }
 
+int ProtoParserPrivate::getMessage(uint64_t id, std::function<bool(const Message &msg)> cb)
+{
+#ifdef USE_SQLITE3
+#else
+    for (auto &msg : _messages)
+    {
+        if (msg.message_id() == id)
+        {
+            cb(msg);
+            break;
+        }
+    }
+    return 0;
+#endif
+}
+
 int ProtoParserPrivate::getMessage(bool before, uint64_t idx, int count, int type, int line, const char *target, std::function<bool(const Message &msg)> cb)
 {
     if (count <= 0)
@@ -856,6 +893,30 @@ int ProtoParserPrivate::update(PullGroupMemberResult &result)
 #endif
 }
 
+int ProtoParserPrivate::update(NotifyMessage &result, std::string &uid, uint64_t &head)
+{
+#ifdef USE_SQLITE3
+    // TODO:
+#else
+    if (result.has_message())
+    {
+        if (result.message().conversation().target() == uid && result.message().conversation().type() == 0)
+        {
+            auto conv = (Conversation *)&result.message().conversation();
+            conv->set_target(result.message().from_user());
+        }
+        _messages.emplace_back(result.message());
+        _messages.sort([](const auto &s1, const auto &s2) {
+            return s1.server_timestamp() < s2.server_timestamp();
+        });
+        // TODO: update head
+#if defined DUMP || defined DUMP_MESSAGE
+        MqttLog(MQTT_LOG_INFO, "msg current: %lld", head);
+#endif
+    }
+#endif
+    return 0;
+}
 int ProtoParserPrivate::update(PullMessageResult &result, uint64_t &head)
 {
     int n = result.message_size();
@@ -937,6 +998,7 @@ int ProtoParserPrivate::update(PullMessageResult &result, uint64_t &head)
     _messages.sort([](const auto &s1, const auto &s2) {
         return s1.server_timestamp() < s2.server_timestamp();
     });
+    // TODO: update head
 #endif
 #if defined DUMP || defined DUMP_MESSAGE
     MqttLog(MQTT_LOG_INFO, "msg current: %lld", head);

+ 3 - 0
src/proto/ProtoParserPrivate.h

@@ -12,9 +12,11 @@ public:
     int getFriendRequest(const char *from, const char *to, int status, int fromReadStatus, int toReadStatus, std::function<bool(const FriendRequest &item)> cb);
     int getUserSetting(int scope, const char *type, std::function<bool(const UserSettingEntry &item)> cb);
     int getFriend(const char *uid, std::function<bool(const Friend &item)> cb);
+    int getFriend(std::function<bool(const Friend &item)> cb);
     int getUser(const char *uid, const char *gid, std::function<bool(const User &item)> cb);
     int getGroup(const char *id, std::function<bool(const GroupInfo &item)> cb);
     int getGroupMembers(const char *id, std::function<bool(const GroupMember &item)> cb);
+    int getMessage(uint64_t id, std::function<bool(const Message &msg)> cb);
     int getMessage(bool before, uint64_t idx, int cnt, int type, int line, const char *target, std::function<bool(const Message &msg)> cb);
     int getConversation(const char *keyword, const char *types, const char *lines, std::function<bool(const Message &msg)> cb);
 
@@ -32,6 +34,7 @@ public:
     int  update(GetUserSettingResult &result);
     int  update(GroupInfo &result);
     int  update(PullGroupMemberResult &result);
+    int  update(NotifyMessage &result, std::string &uid, uint64_t &head);
     int  update(PullMessageResult &result, uint64_t &head);
     void test();
 

+ 74 - 22
src/proto/WFCMessage.pb.cc

@@ -540,6 +540,7 @@ PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT ModifyMyInfoRequestDefaultTypeI
 constexpr NotifyMessage::NotifyMessage(
   ::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized)
   : target_(&::PROTOBUF_NAMESPACE_ID::internal::fixed_address_empty_string)
+  , message_(nullptr)
   , head_(int64_t{0})
   , type_(0){}
 struct NotifyMessageDefaultTypeInternal {
@@ -15462,19 +15463,27 @@ class NotifyMessage::_Internal {
  public:
   using HasBits = decltype(std::declval<NotifyMessage>()._has_bits_);
   static void set_has_type(HasBits* has_bits) {
-    (*has_bits)[0] |= 4u;
+    (*has_bits)[0] |= 8u;
   }
   static void set_has_head(HasBits* has_bits) {
-    (*has_bits)[0] |= 2u;
+    (*has_bits)[0] |= 4u;
   }
   static void set_has_target(HasBits* has_bits) {
     (*has_bits)[0] |= 1u;
   }
+  static const ::Message& message(const NotifyMessage* msg);
+  static void set_has_message(HasBits* has_bits) {
+    (*has_bits)[0] |= 2u;
+  }
   static bool MissingRequiredFields(const HasBits& has_bits) {
-    return ((has_bits[0] & 0x00000006) ^ 0x00000006) != 0;
+    return ((has_bits[0] & 0x0000000c) ^ 0x0000000c) != 0;
   }
 };
 
+const ::Message&
+NotifyMessage::_Internal::message(const NotifyMessage* msg) {
+  return *msg->message_;
+}
 NotifyMessage::NotifyMessage(::PROTOBUF_NAMESPACE_ID::Arena* arena,
                          bool is_message_owned)
   : ::PROTOBUF_NAMESPACE_ID::MessageLite(arena, is_message_owned) {
@@ -15496,6 +15505,11 @@ NotifyMessage::NotifyMessage(const NotifyMessage& from)
     target_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_target(), 
       GetArenaForAllocation());
   }
+  if (from._internal_has_message()) {
+    message_ = new ::Message(*from.message_);
+  } else {
+    message_ = nullptr;
+  }
   ::memcpy(&head_, &from.head_,
     static_cast<size_t>(reinterpret_cast<char*>(&type_) -
     reinterpret_cast<char*>(&head_)) + sizeof(type_));
@@ -15508,9 +15522,9 @@ target_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlrea
   target_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), "", GetArenaForAllocation());
 #endif // PROTOBUF_FORCE_COPY_DEFAULT_STRING
 ::memset(reinterpret_cast<char*>(this) + static_cast<size_t>(
-    reinterpret_cast<char*>(&head_) - reinterpret_cast<char*>(this)),
+    reinterpret_cast<char*>(&message_) - reinterpret_cast<char*>(this)),
     0, static_cast<size_t>(reinterpret_cast<char*>(&type_) -
-    reinterpret_cast<char*>(&head_)) + sizeof(type_));
+    reinterpret_cast<char*>(&message_)) + sizeof(type_));
 }
 
 NotifyMessage::~NotifyMessage() {
@@ -15523,6 +15537,7 @@ NotifyMessage::~NotifyMessage() {
 inline void NotifyMessage::SharedDtor() {
   GOOGLE_DCHECK(GetArenaForAllocation() == nullptr);
   target_.DestroyNoArena(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete message_;
 }
 
 void NotifyMessage::ArenaDtor(void* object) {
@@ -15542,10 +15557,16 @@ void NotifyMessage::Clear() {
   (void) cached_has_bits;
 
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 0x00000001u) {
-    target_.ClearNonDefaultToEmpty();
+  if (cached_has_bits & 0x00000003u) {
+    if (cached_has_bits & 0x00000001u) {
+      target_.ClearNonDefaultToEmpty();
+    }
+    if (cached_has_bits & 0x00000002u) {
+      GOOGLE_DCHECK(message_ != nullptr);
+      message_->Clear();
+    }
   }
-  if (cached_has_bits & 0x00000006u) {
+  if (cached_has_bits & 0x0000000cu) {
     ::memset(&head_, 0, static_cast<size_t>(
         reinterpret_cast<char*>(&type_) -
         reinterpret_cast<char*>(&head_)) + sizeof(type_));
@@ -15588,6 +15609,14 @@ const char* NotifyMessage::_InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_
         } else
           goto handle_unusual;
         continue;
+      // optional .Message message = 4;
+      case 4:
+        if (PROTOBUF_PREDICT_TRUE(static_cast<uint8_t>(tag) == 34)) {
+          ptr = ctx->ParseMessage(_internal_mutable_message(), ptr);
+          CHK_(ptr);
+        } else
+          goto handle_unusual;
+        continue;
       default:
         goto handle_unusual;
     }  // switch
@@ -15620,13 +15649,13 @@ uint8_t* NotifyMessage::_InternalSerialize(
 
   cached_has_bits = _has_bits_[0];
   // required int32 type = 1;
-  if (cached_has_bits & 0x00000004u) {
+  if (cached_has_bits & 0x00000008u) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt32ToArray(1, this->_internal_type(), target);
   }
 
   // required int64 head = 2;
-  if (cached_has_bits & 0x00000002u) {
+  if (cached_has_bits & 0x00000004u) {
     target = stream->EnsureSpace(target);
     target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteInt64ToArray(2, this->_internal_head(), target);
   }
@@ -15637,6 +15666,14 @@ uint8_t* NotifyMessage::_InternalSerialize(
         3, this->_internal_target(), target);
   }
 
+  // optional .Message message = 4;
+  if (cached_has_bits & 0x00000002u) {
+    target = stream->EnsureSpace(target);
+    target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
+      InternalWriteMessage(
+        4, _Internal::message(this), target, stream);
+  }
+
   if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
     target = stream->WriteRaw(_internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).data(),
         static_cast<int>(_internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size()), target);
@@ -15665,7 +15702,7 @@ size_t NotifyMessage::ByteSizeLong() const {
 // @@protoc_insertion_point(message_byte_size_start:NotifyMessage)
   size_t total_size = 0;
 
-  if (((_has_bits_[0] & 0x00000006) ^ 0x00000006) == 0) {  // All required fields are present.
+  if (((_has_bits_[0] & 0x0000000c) ^ 0x0000000c) == 0) {  // All required fields are present.
     // required int64 head = 2;
     total_size += ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::Int64SizePlusOne(this->_internal_head());
 
@@ -15679,14 +15716,23 @@ size_t NotifyMessage::ByteSizeLong() const {
   // Prevent compiler warnings about cached_has_bits being unused
   (void) cached_has_bits;
 
-  // optional string target = 3;
   cached_has_bits = _has_bits_[0];
-  if (cached_has_bits & 0x00000001u) {
-    total_size += 1 +
-      ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
-        this->_internal_target());
-  }
+  if (cached_has_bits & 0x00000003u) {
+    // optional string target = 3;
+    if (cached_has_bits & 0x00000001u) {
+      total_size += 1 +
+        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::StringSize(
+          this->_internal_target());
+    }
+
+    // optional .Message message = 4;
+    if (cached_has_bits & 0x00000002u) {
+      total_size += 1 +
+        ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::MessageSize(
+          *message_);
+    }
 
+  }
   if (PROTOBUF_PREDICT_FALSE(_internal_metadata_.have_unknown_fields())) {
     total_size += _internal_metadata_.unknown_fields<std::string>(::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString).size();
   }
@@ -15708,14 +15754,17 @@ void NotifyMessage::MergeFrom(const NotifyMessage& from) {
   (void) cached_has_bits;
 
   cached_has_bits = from._has_bits_[0];
-  if (cached_has_bits & 0x00000007u) {
+  if (cached_has_bits & 0x0000000fu) {
     if (cached_has_bits & 0x00000001u) {
       _internal_set_target(from._internal_target());
     }
     if (cached_has_bits & 0x00000002u) {
-      head_ = from.head_;
+      _internal_mutable_message()->::Message::MergeFrom(from._internal_message());
     }
     if (cached_has_bits & 0x00000004u) {
+      head_ = from.head_;
+    }
+    if (cached_has_bits & 0x00000008u) {
       type_ = from.type_;
     }
     _has_bits_[0] |= cached_has_bits;
@@ -15732,6 +15781,9 @@ void NotifyMessage::CopyFrom(const NotifyMessage& from) {
 
 bool NotifyMessage::IsInitialized() const {
   if (_Internal::MissingRequiredFields(_has_bits_)) return false;
+  if (_internal_has_message()) {
+    if (!message_->IsInitialized()) return false;
+  }
   return true;
 }
 
@@ -15749,9 +15801,9 @@ void NotifyMessage::InternalSwap(NotifyMessage* other) {
   ::PROTOBUF_NAMESPACE_ID::internal::memswap<
       PROTOBUF_FIELD_OFFSET(NotifyMessage, type_)
       + sizeof(NotifyMessage::type_)
-      - PROTOBUF_FIELD_OFFSET(NotifyMessage, head_)>(
-          reinterpret_cast<char*>(&head_),
-          reinterpret_cast<char*>(&other->head_));
+      - PROTOBUF_FIELD_OFFSET(NotifyMessage, message_)>(
+          reinterpret_cast<char*>(&message_),
+          reinterpret_cast<char*>(&other->message_));
 }
 
 std::string NotifyMessage::GetTypeName() const {

+ 116 - 6
src/proto/WFCMessage.pb.h

@@ -8307,6 +8307,7 @@ class NotifyMessage final :
 
   enum : int {
     kTargetFieldNumber = 3,
+    kMessageFieldNumber = 4,
     kHeadFieldNumber = 2,
     kTypeFieldNumber = 1,
   };
@@ -8328,6 +8329,24 @@ class NotifyMessage final :
   std::string* _internal_mutable_target();
   public:
 
+  // optional .Message message = 4;
+  bool has_message() const;
+  private:
+  bool _internal_has_message() const;
+  public:
+  void clear_message();
+  const ::Message& message() const;
+  PROTOBUF_NODISCARD ::Message* release_message();
+  ::Message* mutable_message();
+  void set_allocated_message(::Message* message);
+  private:
+  const ::Message& _internal_message() const;
+  ::Message* _internal_mutable_message();
+  public:
+  void unsafe_arena_set_allocated_message(
+      ::Message* message);
+  ::Message* unsafe_arena_release_message();
+
   // required int64 head = 2;
   bool has_head() const;
   private:
@@ -8367,6 +8386,7 @@ class NotifyMessage final :
   ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
   mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
   ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr target_;
+  ::Message* message_;
   int64_t head_;
   int32_t type_;
   friend struct ::TableStruct_WFCMessage_2eproto;
@@ -24303,7 +24323,7 @@ ModifyMyInfoRequest::entry() const {
 
 // required int32 type = 1;
 inline bool NotifyMessage::_internal_has_type() const {
-  bool value = (_has_bits_[0] & 0x00000004u) != 0;
+  bool value = (_has_bits_[0] & 0x00000008u) != 0;
   return value;
 }
 inline bool NotifyMessage::has_type() const {
@@ -24311,7 +24331,7 @@ inline bool NotifyMessage::has_type() const {
 }
 inline void NotifyMessage::clear_type() {
   type_ = 0;
-  _has_bits_[0] &= ~0x00000004u;
+  _has_bits_[0] &= ~0x00000008u;
 }
 inline int32_t NotifyMessage::_internal_type() const {
   return type_;
@@ -24321,7 +24341,7 @@ inline int32_t NotifyMessage::type() const {
   return _internal_type();
 }
 inline void NotifyMessage::_internal_set_type(int32_t value) {
-  _has_bits_[0] |= 0x00000004u;
+  _has_bits_[0] |= 0x00000008u;
   type_ = value;
 }
 inline void NotifyMessage::set_type(int32_t value) {
@@ -24331,7 +24351,7 @@ inline void NotifyMessage::set_type(int32_t value) {
 
 // required int64 head = 2;
 inline bool NotifyMessage::_internal_has_head() const {
-  bool value = (_has_bits_[0] & 0x00000002u) != 0;
+  bool value = (_has_bits_[0] & 0x00000004u) != 0;
   return value;
 }
 inline bool NotifyMessage::has_head() const {
@@ -24339,7 +24359,7 @@ inline bool NotifyMessage::has_head() const {
 }
 inline void NotifyMessage::clear_head() {
   head_ = int64_t{0};
-  _has_bits_[0] &= ~0x00000002u;
+  _has_bits_[0] &= ~0x00000004u;
 }
 inline int64_t NotifyMessage::_internal_head() const {
   return head_;
@@ -24349,7 +24369,7 @@ inline int64_t NotifyMessage::head() const {
   return _internal_head();
 }
 inline void NotifyMessage::_internal_set_head(int64_t value) {
-  _has_bits_[0] |= 0x00000002u;
+  _has_bits_[0] |= 0x00000004u;
   head_ = value;
 }
 inline void NotifyMessage::set_head(int64_t value) {
@@ -24426,6 +24446,96 @@ inline void NotifyMessage::set_allocated_target(std::string* target) {
   // @@protoc_insertion_point(field_set_allocated:NotifyMessage.target)
 }
 
+// optional .Message message = 4;
+inline bool NotifyMessage::_internal_has_message() const {
+  bool value = (_has_bits_[0] & 0x00000002u) != 0;
+  PROTOBUF_ASSUME(!value || message_ != nullptr);
+  return value;
+}
+inline bool NotifyMessage::has_message() const {
+  return _internal_has_message();
+}
+inline void NotifyMessage::clear_message() {
+  if (message_ != nullptr) message_->Clear();
+  _has_bits_[0] &= ~0x00000002u;
+}
+inline const ::Message& NotifyMessage::_internal_message() const {
+  const ::Message* p = message_;
+  return p != nullptr ? *p : reinterpret_cast<const ::Message&>(
+      ::_Message_default_instance_);
+}
+inline const ::Message& NotifyMessage::message() const {
+  // @@protoc_insertion_point(field_get:NotifyMessage.message)
+  return _internal_message();
+}
+inline void NotifyMessage::unsafe_arena_set_allocated_message(
+    ::Message* message) {
+  if (GetArenaForAllocation() == nullptr) {
+    delete reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(message_);
+  }
+  message_ = message;
+  if (message) {
+    _has_bits_[0] |= 0x00000002u;
+  } else {
+    _has_bits_[0] &= ~0x00000002u;
+  }
+  // @@protoc_insertion_point(field_unsafe_arena_set_allocated:NotifyMessage.message)
+}
+inline ::Message* NotifyMessage::release_message() {
+  _has_bits_[0] &= ~0x00000002u;
+  ::Message* temp = message_;
+  message_ = nullptr;
+#ifdef PROTOBUF_FORCE_COPY_IN_RELEASE
+  auto* old =  reinterpret_cast<::PROTOBUF_NAMESPACE_ID::MessageLite*>(temp);
+  temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+  if (GetArenaForAllocation() == nullptr) { delete old; }
+#else  // PROTOBUF_FORCE_COPY_IN_RELEASE
+  if (GetArenaForAllocation() != nullptr) {
+    temp = ::PROTOBUF_NAMESPACE_ID::internal::DuplicateIfNonNull(temp);
+  }
+#endif  // !PROTOBUF_FORCE_COPY_IN_RELEASE
+  return temp;
+}
+inline ::Message* NotifyMessage::unsafe_arena_release_message() {
+  // @@protoc_insertion_point(field_release:NotifyMessage.message)
+  _has_bits_[0] &= ~0x00000002u;
+  ::Message* temp = message_;
+  message_ = nullptr;
+  return temp;
+}
+inline ::Message* NotifyMessage::_internal_mutable_message() {
+  _has_bits_[0] |= 0x00000002u;
+  if (message_ == nullptr) {
+    auto* p = CreateMaybeMessage<::Message>(GetArenaForAllocation());
+    message_ = p;
+  }
+  return message_;
+}
+inline ::Message* NotifyMessage::mutable_message() {
+  ::Message* _msg = _internal_mutable_message();
+  // @@protoc_insertion_point(field_mutable:NotifyMessage.message)
+  return _msg;
+}
+inline void NotifyMessage::set_allocated_message(::Message* message) {
+  ::PROTOBUF_NAMESPACE_ID::Arena* message_arena = GetArenaForAllocation();
+  if (message_arena == nullptr) {
+    delete message_;
+  }
+  if (message) {
+    ::PROTOBUF_NAMESPACE_ID::Arena* submessage_arena =
+        ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper<::Message>::GetOwningArena(message);
+    if (message_arena != submessage_arena) {
+      message = ::PROTOBUF_NAMESPACE_ID::internal::GetOwnedMessage(
+          message_arena, message, submessage_arena);
+    }
+    _has_bits_[0] |= 0x00000002u;
+  } else {
+    _has_bits_[0] &= ~0x00000002u;
+  }
+  message_ = message;
+  // @@protoc_insertion_point(field_set_allocated:NotifyMessage.message)
+}
+
 // -------------------------------------------------------------------
 
 // PullMessageRequest

+ 18 - 13
src/proto/jsonUtils.cpp

@@ -421,6 +421,11 @@ void toJson(rapidjson::Writer<rapidjson::StringBuffer> &writer, const NotifyMess
     WRITE_INT(type);
     WRITE_INT64(head);
     WRITE_STR_OPT(target);
+    if (info.has_message())
+    {
+        writer.Key("message");
+        toJson(writer, info.message());
+    }
     writer.EndObject();
 }
 
@@ -713,7 +718,7 @@ bool parseJson(std::string &str, AddFriendRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
 
@@ -729,7 +734,7 @@ bool parseJson(std::string &str, AddGroupMemberRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     par.set_group_id(doc["group_id"].GetString());
@@ -776,7 +781,7 @@ bool parseJson(std::string &str, CreateGroupRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return "";
     }
     {
@@ -813,7 +818,7 @@ bool parseJson(std::string &str, IDBuf &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     par.set_id(doc["id"].GetString());
@@ -825,7 +830,7 @@ bool parseJson(std::string &str, DismissGroupRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     par.set_group_id(doc["group_id"].GetString());
@@ -853,7 +858,7 @@ bool parseJson(std::string &str, PullUserRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     auto arr = doc["request"].GetArray();
@@ -873,7 +878,7 @@ bool parseJson(std::string &str, QuitGroupRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     par.set_group_id(doc["group_id"].GetString());
@@ -901,7 +906,7 @@ bool parseJson(std::string &str, PullGroupMemberRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     par.set_target(doc["target"].GetString());
@@ -914,7 +919,7 @@ bool parseJson(std::string &str, HandleFriendRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
 
@@ -930,7 +935,7 @@ bool parseJson(std::string &str, LoadRemoteMessages &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     if (doc.HasMember("conversation"))
@@ -949,7 +954,7 @@ bool parseJson(std::string &str, ModifyMyInfoRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     auto arr = doc["entry"].GetArray();
@@ -968,7 +973,7 @@ bool parseJson(std::string &str, PullMessageRequest &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     par.set_id(doc["id"].GetInt64());
@@ -983,7 +988,7 @@ bool parseJson(std::string &str, ModifyUserSettingReq &par)
     rapidjson::Document doc;
     if (str.length() <= 0 || doc.Parse(str.c_str()).HasParseError())
     {
-        MqttLog(MQTT_LOG_ERROR, "parse failed: %d", doc.GetParseError());
+        MqttLog(LOG_ERROR, LOG_TYPE_DATA, "parse failed: %d", doc.GetParseError());
         return false;
     }
     par.set_scope(doc["scope"].GetInt());

Неке датотеке нису приказане због велике количине промена