Пример #1
0
 private static MessageGroup ReadMessageGroup(BinaryReader BR, Encoding E)
 {
     MessageGroup MG = new MessageGroup();
       MG.Category    = BR.ReadByte();
       MG.Language    = BR.ReadByte();
       MG.ID          = BR.ReadByte();
       MG.ParentGroup = BR.ReadByte();
       MG.Title       = E.GetString(BR.ReadBytes(32)).TrimEnd('\0');
       MG.Description = E.GetString(BR.ReadBytes(32)).TrimEnd('\0');
     uint MessageCount = BR.ReadUInt32();
       /* MessageBytes */ BR.ReadUInt32();
       for (int i = 0; i < MessageCount; ++i)
     MG.Messages.Add(AutoTranslator.ReadMessage(BR, E));
       return MG;
 }
Пример #2
0
        /// <summary>组合组消息</summary>
        /// <param name="message">消息</param>
        /// <param name="remoteIdentity">远程标识</param>
        /// <returns></returns>
        protected virtual Message JoinGroup(GroupMessage message, Object remoteIdentity = null)
        {
            var key = String.Format("{0}#{1}", remoteIdentity, message.Identity);

            MessageGroup mg = null;
            if (!groups.TryGetValue(key, out mg))
            {
                mg = new MessageGroup();
                mg.Identity = message.Identity;
                groups.Add(key, mg);
            }

            // 加入到组,如果返回false,表示未收到所有消息
            if (!mg.Add(message))
            {
                WriteLog("接收分组 Identity={0} {1}/{2} [{3}] 已完成:{4}/{5}", message.Identity, message.Index, message.Count, message.Data == null ? 0 : message.Data.Length, mg.Count, mg.Total);

                return null;
            }

            WriteLog("接收分组 Identity={0} {1}/{2} [{3}] 已完成:{4}/{5}", message.Identity, message.Index, message.Count, message.Data == null ? 0 : message.Data.Length, mg.Count, mg.Total);

            // 否则,表示收到所有消息
            groups.Remove(key);

            // 读取真正的消息
            return mg.GetMessage();
        }
Пример #3
0
 /// <summary>发送消息。如果有响应,可在消息到达事件<see cref="OnReceived"/>中获得。这里会实现大消息分包。</summary>
 /// <param name="message"></param>
 public virtual void Send(Message message)
 {
     var ms = message.GetStream();
     WriteLog("发送消息 [{0}] {1}", ms.Length, message);
     if (MaxMessageSize <= 0 || ms.Length < MaxMessageSize)
         OnSend(ms);
     else
     {
         var mg = new MessageGroup();
         mg.Split(ms, MaxMessageSize, message.Header);
         var count = 0;
         foreach (var item in mg)
         {
             if (item.Index == 1) count = item.Count;
             ms = item.GetStream();
             WriteLog("发送分组 Identity={0} {1}/{2} [{3}] [{4}]", item.Identity, item.Index, count, item.Data == null ? 0 : item.Data.Length, ms.Length);
             Debug.Assert(item.Index == count || ms.Length == MaxMessageSize, "分拆的组消息大小不合适!");
             OnSend(ms);
         }
     }
 }
Пример #4
0
        /// <summary>
        /// Finds the handle corresponding to the message group. If no such handle exists it will be created.
        /// </summary>
        /// <param name="group">The message group.</param>
        /// <returns>The ID of the handle.</returns>
        private long GetOrCreateHandle(MessageGroup group)
        {
            // Check for existing handle
            string checkHandle = String.Format("SELECT ROWID FROM {0} WHERE id = '{1}' AND service = '{2}'", HandleTable, group.Address, MessageService);
            object existingHandleId = Scalar(checkHandle);
            if (existingHandleId != null)
                return (long)existingHandleId;

            // Insert new handle
            string insertHandle = String.Format("INSERT INTO {0} (id, country, service, uncanonicalized_id) VALUES ('{1}', '{2}', '{3}', '{1}')", HandleTable, group.Address, group.CountryCode, MessageService);
            Query(insertHandle);
            return LastInsertId;
        }
Пример #5
0
        /// <summary>
        /// Finds the chat corresponding to the message group. If no such chat exists it will be created. The corresponding handle will also be created.
        /// </summary>
        /// <param name="group">The message group.</param>
        /// <returns>The ID of the chat.</returns>
        private long GetOrCreateChat(MessageGroup group)
        {
            // Check for existing chat
            string checkChat = String.Format("SELECT ROWID FROM {0} WHERE chat_identifier = '{1}' AND service_name = '{2}'", ChatTable, group.Address, MessageService);
            object existingChatId = Scalar(checkChat);
            if (existingChatId != null)
                return  (long)existingChatId;

            // Insert new chat
            string insertChat = String.Format("INSERT INTO {0} (guid, style, state, chat_identifier, service_name) VALUES ('{1}', {2}, {3}, '{4}', '{5}')", ChatTable, string.Format("{0};-;{1}", MessageService, group.Address), 45, 2, group.Address, MessageService);
            Query(insertChat);
            long chatId = LastInsertId;

            // Get or create handle
            long handleId = GetOrCreateHandle(group);

            // Insert join
            string insertJoin = String.Format("INSERT INTO {0} (chat_id, handle_id) VALUES ({1}, {2})", ChatHandleJoinTable, chatId, handleId);
            Query(insertJoin);

            return chatId;
        }
Пример #6
0
        /// <summary>
        /// Writes a group of messages to the database.
        /// </summary>
        /// <param name="group">The group of messages.</param>
        public void SaveMessageGroup(MessageGroup group)
        {
            using (SQLiteTransaction transaction = _connection.BeginTransaction())
            {
                // Get or create handle and chat
                long handleId = GetOrCreateHandle(group);
                long chatId = GetOrCreateChat(group);

                // Insert messages using a prepared statement
                using (var command = new SQLiteCommand(_connection))
                {
                    // Build query
                    command.CommandText = String.Format("INSERT INTO {0} " +
                        "(guid, text, handle_id, country, version, service, date, date_read, date_delivered, is_finished, is_from_me, is_prepared, is_read, is_sent) " +
                        "VALUES (?, ?, {1}, '{2}', {3}, '{4}', ?, ?, ?, {5}, ?, {6}, ?, ?)",
                        MessageTable,
                        handleId,
                        group.CountryCode.ToString().ToLower(),
                        1,
                        MessageService,
                        1,
                        1);

                    // Create and setup statement parameters
                    var guid = new SQLiteParameter();
                    var text = new SQLiteParameter();
                    var date = new SQLiteParameter();
                    var dateRead = new SQLiteParameter();
                    var dateDelivered = new SQLiteParameter();
                    var isFromMe = new SQLiteParameter();
                    var isRead = new SQLiteParameter();
                    var isSent = new SQLiteParameter();
                    command.Parameters.Add(guid);
                    command.Parameters.Add(text);
                    command.Parameters.Add(date);
                    command.Parameters.Add(dateRead);
                    command.Parameters.Add(dateDelivered);
                    command.Parameters.Add(isFromMe);
                    command.Parameters.Add(isRead);
                    command.Parameters.Add(isSent);

                    // Execute the statement for each message
                    foreach (var message in group)
                    {
                        // Fill prepared statement
                        guid.Value = Guid.NewGuid().ToString().ToUpper();
                        text.Value = message.Text;
                        date.Value = message.AppleTimestamp;
                        dateRead.Value = message.AppleTimestamp;
                        dateDelivered.Value = message.AppleTimestamp;
                        isFromMe.Value = (message.Type == MessageType.Outgoing) ? 1 : 0;
                        isRead.Value = (message.Type == MessageType.Incoming) ? 1 : 0;
                        isSent.Value = (message.Type == MessageType.Outgoing) ? 1 : 0;
                        command.ExecuteNonQuery();

                        // Insert join
                        long messageId = LastInsertId;
                        string insertJoin = String.Format("INSERT INTO {0} (chat_id, message_id) VALUES ({1}, {2})", ChatMessageJoinTable, chatId, messageId);
                        Query(insertJoin);
                    }
                }

                // Commit changes
                transaction.Commit();
            }
        }