1: private string AnalyCustomFace(byte[] IMBytes)
2: {
3: List<byte> al = new List<byte>();
4: List<string> Faces = new List<string>();
5: byte[] tempBytes;
6: int bytesSize = 0;
7: int shortcutSize = 0;
8: bool FaceOrPic = true;//true是自定义表情,false是截屏
9: string FaceName = "";
10: byte[] FaceNameBytes;
11: byte[] facebytes;
12: al.AddRange(IMBytes);
13:
14: for (int i = 0; i < al.Count - 1; i++)
15: {
16:
17: if ((FaceType)al[i] == FaceType.DEFAULT && (byte)al[i + 1] >= 0x40 && (byte)al[i + 1] <= 0xC7)//QQ的表情符号是0x14开头的,下一字节表示表情索引号。0x15开头的是自定义表情。这里处理系统表情,以免乱码。
18: {
19: string face = string.Format("<img src=\"face/{0}.gif\" />", al[i + 1].ToString());
20: facebytes = Encoding.GetEncoding("GBK").GetBytes(face);
21: al.RemoveRange(i, 2);
22: al.InsertRange(i, facebytes);
23: i += facebytes.Length - 1;
24: continue;
25: }
26:
27: if ((FaceType)al[i] == FaceType.CUSTOM && (FaceType)al[i + 1] == FaceType.NEW_CUSTOM)
28: {
29: int extSize = (int)(al[i + 2] - 0x30 + 1);//扩展名长度
30: shortcutSize = (int)(al[i + 2 + 32 + 1 + extSize + 1] - 0x41);//快捷键长度
31: bytesSize = 3 + 32 + 1 + extSize + 1 + shortcutSize;
32: tempBytes = new byte[bytesSize];
33: al.CopyTo(i, tempBytes, 0, bytesSize);
34: FaceNameBytes = new byte[36];
35: Array.Copy(tempBytes, 3, FaceNameBytes, 0, 36);
36: FaceName = Encoding.GetEncoding("GBK").GetString(FaceNameBytes);
37: string face = string.Format("[CustomFace={0}]", FaceName);
38: facebytes = Encoding.GetEncoding("GBK").GetBytes(face);
39: al.RemoveRange(i, bytesSize);//删除原数据
40: al.InsertRange(i, facebytes);//插入自己转换后的数据
41: Faces.Add(FaceName);//加入队列,因为和群自定义表情不会同时在同一条消息里出现,因此不会有问题
42: i += facebytes.Length - 1;
43: }
44: else if ((FaceType)al[i] == FaceType.CUSTOM && (FaceType)al[i + 1] == FaceType.EXISTING_CUSTOM)
45: {
46: FaceName = Faces[al[i + 2] - 0x41];
47: string face = string.Format("[CustomFace={0}]", FaceName);
48: facebytes = Encoding.GetEncoding("GBK").GetBytes(face);
49: al.RemoveRange(i, 3);//删除原数据
50: al.InsertRange(i, facebytes);//插入自己转换后的数据
51: i += facebytes.Length - 1;
52:
53: }
54: else if ((FaceType)al[i] == FaceType.CUSTOM && (FaceType)al[i + 1] == FaceType.NEW_SERVER_SIDE_CUSTOM)//这里转换自定义表情和贴图 FaceType.CUSTOM表示是自定义表情或贴图, FaceType.NEW_SERVER_SIDE_CUSTOM表示是在这条消息里第一次出现的自定义表情或贴图
55: {
56: tempBytes = new byte[3];//这里获取表情数据的长度
57: al.CopyTo(i + 2, tempBytes, 0, 3);
58: bytesSize = Convert.ToInt32(Encoding.GetEncoding("GBK").GetString(tempBytes));
59: tempBytes = new byte[bytesSize];
60: al.CopyTo(i, tempBytes, 0, bytesSize);
61:
62: if (tempBytes[5] == 0x65)//如果是'e'表示是自定义表情
63: {
64: FaceOrPic = true;
65: }
66: else if (tempBytes[5] == 0x6B)//如果是'k'表示是贴图 自定义表情和贴图的区别在于文件名不同,自定义表情的文件名是MD5字串加扩展名,贴图是{GUID}加扩展名
67: {
68: FaceOrPic = false;
69: }
70:
71: shortcutSize = (int)(tempBytes[6] - 0x41);//快捷键长度
72:
73: if (FaceOrPic)
74: {
75: FaceNameBytes = new byte[36];//MD5+".gif"一共36个字节
76: Array.Copy(tempBytes, 0x31, FaceNameBytes, 0, 36);
77: FaceName = Encoding.GetEncoding("GBK").GetString(FaceNameBytes);
78: string face = string.Format("[CustomFace={0}]", FaceName);
79: facebytes = Encoding.GetEncoding("GBK").GetBytes(face);
80: al.RemoveRange(i, bytesSize);//删除原数据
81: al.InsertRange(i, facebytes);//插入自己转换后的数据
82: }
83: else
84: {
85: FaceNameBytes = new byte[42];//{GUID}+".gif"一共42个字节
86: Array.Copy(tempBytes, 0x31, FaceNameBytes, 0, 42);
87: FaceName = Encoding.GetEncoding("GBK").GetString(FaceNameBytes).Replace("{", "").Replace("}", "");
88: string face = string.Format("[CustomFace={0}]", FaceName);
89: facebytes = Encoding.GetEncoding("GBK").GetBytes(face);
90: al.RemoveRange(i, bytesSize);
91: al.InsertRange(i, facebytes);
92: }
93:
94: Faces.Add(FaceName);//加入队列
95: i += facebytes.Length - 1;
96:
97: }
98: else if ((FaceType)al[i] == FaceType.CUSTOM && (FaceType)al[i + 1] == FaceType.EXISTING_SERVER_SIDE_CUSTOM_SIDE)//如果是本消息中已经出现过的表情或截图
99: {
100: tempBytes = new byte[3];
101: al.CopyTo(i + 2, tempBytes, 0, 3);
102: bytesSize = Convert.ToInt32(Encoding.GetEncoding("GBK").GetString(tempBytes));
103:
104: tempBytes = new byte[bytesSize];
105:
106: al.CopyTo(i, tempBytes, 0, bytesSize);
107:
108: FaceName = Faces[tempBytes[5] - 0x41];//从队列中取出
109: string face = string.Format("[CustomFace={0}]", FaceName);
110: facebytes = Encoding.GetEncoding("GBK").GetBytes(face);
111: al.RemoveRange(i, bytesSize);
112: al.InsertRange(i, facebytes);
113:
114: i += facebytes.Length - 1;
115: }
116: }
117:
118: tempBytes = new byte[al.Count];
119: al.CopyTo(0, tempBytes, 0, tempBytes.Length);//ArrayList转byte[]
120: return Encoding.GetEncoding("GBK").GetString(tempBytes);//byte[]转String
121: }