让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,完工,可以正常发送超长群消息了