zoukankan      html  css  js  c++  java
  • 让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,完工,可以正常发送超长群消息了

  • 相关阅读:
    分析存储过程重编译的起因以及避免
    存储过程重编译的优点、缺点、确定引发语句
    运用计划缓冲的建议
    查询计划Hash和查询Hash
    执行计划的重用
    执行计划组件、组件、老化
    执行计划的生成
    统计的基本操作语法 <第五篇>
    javascript 之 location.href、跨窗口调用函数
    git 删除远程分支和本地分支
  • 原文地址:https://www.cnblogs.com/lersh/p/1176284.html
Copyright © 2011-2022 走看看