让LumaQQ.NET支持发送超长群消息

        之前我们修改了LumaQQ.NET,让他能发送超长消息了。现在我们再来看看,怎么让其支持发送群超长消息。

        可能有人说,这个简单,我照着发送普通消息的方法写一个发送群的不是一样吗?

         呵呵,我一开始也是这么想的,可惜,当写完验证时,我发现我错了,能发出去,可是接受不到……

        囧,这到底是怎么回事?难道格式或者其他什么地方有问题?

        好吧,具体原因我不吊大家胃口了,原因是MessageId。

        群消息不像普通消息,MessageId需要自己指定,不然随机MessageId的话,就没法拼起来成为完整消息了。好了,知道这点就好改了。

        先来修改ClusterManager类,修改三个SendClusterIM的方法,更改参数类型

   1: public void SendClusterIM(int clusterId, string message)
   2: {
   3:     SendClusterIM(clusterId, message, new FontStyle());
   4: }
   5: /// <summary>发送群信息
   6: /// Sends the cluster IM.
   7: /// </summary>
   8: /// <param name="clusterId">The cluster id.</param>
   9: /// <param name="message">The message.</param>
  10: /// <param name="totalFragments">The total fragments.</param>
  11: /// <param name="fragmentSequence">The fragment sequence.</param>
  12: public void SendClusterIM(int clusterId, string message, FontStyle fontStyle)
  13: {
  14:     int MaxByte = 690;//群消息最长长度690
  15:  
  16:     //
  17:     //发送长信息的功能由 @蓝色的风之精灵 补充
  18:     //
  19:     if (Encoding.GetEncoding(QQGlobal.QQ_CHARSET_DEFAULT).GetBytes(message).Length > MaxByte)//判断是不是要分段发送
  20:     {
  21:         int MessageId = Utils.Util.Random.Next();//生成随即的MessageId
  22:         List<byte> messageBytes = new List<byte>();
  23:         messageBytes.AddRange(Utils.Util.GetBytes(message));
  24:         int messageSize = messageBytes.Count;
  25:  
  26:         int totalFragments = ((messageSize % MaxByte) > 0) ? (messageSize / MaxByte + 1) : (messageSize / MaxByte);//计算分片数
  27:         for (int fragementSequence = 0; fragementSequence < totalFragments; fragementSequence++)
  28:         {
  29:             int index = fragementSequence * MaxByte;
  30:             int BytesSize = ((messageSize - index) > MaxByte) ? MaxByte : (messageSize - index);//不能每次都申请最大长度的byte数组,不然字体会出问题
  31:             byte[] messageFragementBytes = new byte[BytesSize];
  32:  
  33:             messageBytes.CopyTo(index, messageFragementBytes, 0, BytesSize);
  34:             SendClusterIM(clusterId, messageFragementBytes,MessageId, totalFragments, fragementSequence, fontStyle);
  35:             
  36:         }
  37:     }
  38:     else
  39:     {
  40:         SendClusterIM(clusterId, Utils.Util.GetBytes(message),Utils.Util.Random.Next(), 1, 0, fontStyle);
  41:     }
  42: }
  43: /// <summary>发送群信息
  44: /// Sends the cluster IM.
  45: /// </summary>
  46: /// <param name="clusterId">The cluster id.</param>
  47: /// <param name="message">The message.</param>
  48: /// <param name="totalFragments">The total fragments.</param>
  49: /// <param name="fragmentSequence">The fragment sequence.</param>
  50: /// <param name="fontStyle">The font style.</param>
  51: public void SendClusterIM(int clusterId, byte[] messageByte,int MessageId, int totalFragments, int fragmentSequence, FontStyle fontStyle)
  52: {
  53:     ClusterSendIMExPacket packet = new ClusterSendIMExPacket(QQUser);
  54:     packet.ClusterId = clusterId;
  55:     packet.Message = messageByte;
  56:     packet.MessageId = (ushort)MessageId;//指定MessageId
  57:     packet.TotalFragments = totalFragments;
  58:     packet.FragmentSequence = fragmentSequence;
  59:     packet.FontStyle = fontStyle;
  60:     QQClient.PacketManager.SendPacket(packet, QQPort.Main.Name);
  61: }

 

        然后去ClusterSendIMExPacket类,将

public string Message { get; set; }

        改为

public byte[] Message { get; set; }

 

        最后修改PutBody方法

   1: protected override void PutBody(ByteBuffer buf)
   2: {
   3:     // 命令类型
   4:     buf.Put((byte)SubCommand);
   5:     // 群内部ID
   6:     buf.PutInt(ClusterId);
   7:     // 后面数据的长度,这个长度需要根据后面的长度计算才能知道,
   8:     // 所以先占个位置        
   9:     int pos = buf.Position;
  10:     buf.PutChar((char)0);
  11:     // 未知的2字节
  12:     buf.PutChar((char)1);
  13:     // 分片数
  14:     buf.Put((byte)TotalFragments);
  15:     // 分片序号
  16:     buf.Put((byte)FragmentSequence);
  17:     if (MessageId == 0)
  18:     {
  19:         MessageId = (ushort)this.Sequence;
  20:     }
  21:     // 消息id
  22:     buf.PutUShort(MessageId);
  23:     // 未知4字节
  24:     buf.PutInt(0);
  25:  
  26:     // 过滤字符串的方法以后再写,这里先注释掉
  27:  
  28:     // 以0结束的消息,首先我们要根据用户设置的message,解析出一个网络可发送的格式
  29:     // 这一步比较麻烦,暂时想不到好的办法
  30:     //byte[] msgBytes = null;
  31:     //int j, i = 0;
  32:     //while ((j = Message.IndexOf((char)FaceType.DEFAULT, i)) != -1)
  33:     //{
  34:     //    string sub = Message.Substring(i, j);
  35:     //    if (!sub.Equals(""))
  36:     //    {
  37:     //        msgBytes = Utils.Util.GetBytes(sub);
  38:     //        buf.Put(msgBytes);
  39:     //    }
  40:     //    buf.Put((byte)FaceType.DEFAULT);
  41:     //    buf.Put((byte)(Message[j + 1] & 0xFF));
  42:     //    i = j + 2;
  43:     //}
  44:     //if (i < Message.Length)
  45:     //{
  46:     //    string sub = Message.Substring(i);
  47:     //    msgBytes = Utils.Util.GetBytes(sub);
  48:     //    buf.Put(msgBytes);
  49:     //}
  50:  
  51:     buf.Put(Message);//插入消息byte数组
  52:  
  53:     // 只有最后一个分片有空格和字体属性
  54:     if (FragmentSequence == TotalFragments - 1)
  55:     {
  56:         buf.Put((byte)0x20);
  57:         FontStyle.Write(buf);
  58:     }
  59:  
  60:     // 写入长度
  61:     int cur = buf.Position;
  62:     buf.Position = pos;
  63:     buf.PutChar((char)(cur - pos - 2));
  64:     buf.Position = cur;
  65: }

 

        OK,完工,可以正常发送超长群消息了

posted @ 2008-04-29 15:21  蓝色的风之精灵  阅读(2188)  评论(6编辑  收藏  举报