using System;
using System.Text;
using System.Security.Cryptography;
using luckpanda.utility;
using RedQ;
namespace luckpanda.iqq.packet
{
class outpacket
{
//报头报尾起止字节
byte bphead = 0x02, bptail = 0x03, bpnull = 0x00;
//存放请求数据报的内容
byte[] bytes;
///<summary>
///为请求数据报追加常规报头部分
///</summary>
///<param name="bcommand"></param>
void FillHead(byte bcommand)
{
//追加报头首字节
bytes.SetValue(bphead, 0);
//追加版本号
qq.vertion.CopyTo(bytes, 1);
//追加命令号
bytes.SetValue(bpnull, 3);
bytes.SetValue(bcommand, 4);
//追加命令序号
qq.cmdsn.CopyTo(bytes, 5);
//追加QQ帐号
qq.QQNum.CopyTo(bytes, 7);
}
///<summary>
///组装请求报
///</summary>
///<param name="bcommand"></param>
public outpacket(byte bcommand)
{
int flag = 0;
byte[] tmpkeyba;//临时密钥for 0xBA
QQCrypt cipher = new QQCrypt();
switch (bcommand)
{
case 0x91:
//定义报长
bytes = new byte[60];
//追加报头
FillHead(bcommand);
//临时密钥
qq.tmpkey.CopyTo(bytes, 11);
//密文:临时密钥加密个x00
byte[] tmp91 = cipher.QQ_Encrypt(new Byte[15], qq.tmpkey);
//追加密文
tmp91.CopyTo(bytes, 27);
break;
case 0x62:
//定义报长
bytes = new byte[13];
//追加报头
FillHead(bcommand);
//补位
bytes.SetValue(bpnull, 11);
break;
case 0xba:
//临时令牌
byte[] asmtoken = new byte[35];
byte balen = 0x18;
asmtoken.SetValue(balen ,0);
qq.tmptoken.CopyTo(asmtoken, 1);
byte[] asmtail = { 0x03, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
asmtail.CopyTo(asmtoken, 25);
//加密[装配后的令牌]
byte[] bsend = cipher.QQ_Encrypt(asmtoken,qq.tmpkey);
//定义报长
bytes = new byte[12 + qq.tmpkey.Length + bsend.Length];
//追加报头
FillHead(bcommand);
qq.tmpkey.CopyTo(bytes, 11);
bsend.CopyTo(bytes, 11 + qq.tmpkey.Length);
break;
case 0xdd:
//?客户端在xdd时发出的临时密钥是否需要更换?什么规则?未知
qq.tmpkey = new byte[]{0x2E,0xF3,0x2A,0x60,0xDF,0xEC,0x58,0xC9,0x0B,0x75,0xD6,0x4B,0xCF,0x88,0xBE,0x68};
//装配密文
byte[] asmddp1 = { 0, 95, 0, 0, 8, 4, 1, 224 };
#region生成密码验证串
MD5 md5 = MD5.Create();
byte[] asmddtp1 = md5.ComputeHash(qq.QQPsw);
byte[] asmddstr = new byte[asmddtp1.Length + 4];
asmddtp1.CopyTo(asmddstr, 0);
//四个字节的随机数
byte[] asmddtp3 = {0x00, 0x01, 0x02, 0x03};
asmddtp3.CopyTo(asmddstr, asmddtp1.Length);
byte[] asmddp5 = cipher.QQ_Encrypt(asmddstr, qq.pswkey);
//保存密码验证串
qq.pwschk = asmddp5;
#endregion
//装配密文过程
byte[] asmdd = new byte[asmddp1.Length + 1 + qq.token.Length + 2 + asmddp5.Length + 27];
asmddp1.CopyTo(asmdd, 0);
asmdd.SetValue(Convert.ToByte(qq.token.Length), 8);//token length 32?
qq.token.CopyTo(asmdd, 9);
//加分隔符
asmdd.SetValue(Convert.ToByte(0), 9 + qq.token.Length);
//加密码验证串的长度
asmdd.SetValue(Convert.ToByte(asmddp5.Length), 10 + qq.token.Length);
asmddp5.CopyTo(asmdd, 11 + qq.token.Length);
byte[] asmddtp4 = { 0, 20, 214, 73, 213, 51, 88, 203, 88, 241, 11, 220, 55, 122, 216, 114, 224, 75, 195, 202, 47, 14, 0, 3, 0, 126, 251 };
asmddtp4.CopyTo(asmdd, qq.token.Length + asmddp5.Length + 11);
byte[] asmdd2 = cipher.QQ_Encrypt(asmdd, qq.tmpkey);
bytes = new byte[11 + qq.tmpkey.Length + asmdd2.Length + 1];
FillHead(bcommand);
qq.tmpkey.CopyTo(bytes, 11);
asmdd2.CopyTo(bytes, 11 + qq.tmpkey.Length);
break;
case 0x22:
//part 1 count=36
byte[] asm22p1 = {0x00,0x00,0x00,0x20};
//part 2 pwschk 密码验证串0x20
byte[] asm22p2 = { 0xd1, 0x0a, 0x06, 0x23, 0xb3, 0x7a, 0x9c, 0x23, 0xa2, 0x30,
0x7b, 0x13, 0x5e, 0x64, 0xee, 0x81, 0x33, 0x87, 0x15, 0x61,
0x0d, 0x0c, 0x2c, 0x39, 0x94, 0xf9, 0x00, 0xec, 0xa3, 0x34,
0x35, 0xb0 };
//part 3 count=16
byte[] asm22p3 = {0x06,0xf2,0xb0,0xca,0xf0,0xdd,0x0c,0x32,0xf7,0xc6,0x98,0x19,0x85,0x89,0xc3,0x12 };
//part 4 count=79
byte[] asm22p4 = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x79,
0x1D,0x5D,0x16,0xB8,0x1D,0xF4,0x9E,0xDA,0x09,0xE5,0x2E,0x03,0x04,0x73,0x44,0x39,0x0A,0x00,0x00,0x00,
0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0xAE,0xE9,0x53,0x58,0x11,0xE1,0xAC,0x49,0x91,0x46,0x17,0xAD,0x89,0xF8,0x62,0x0A,0x20};
//part 5 count=332
byte[] asm22p5 = {0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x01,0xF1,0xA6,0x78,0xE9,0x00,0x10,0xD9,
0xF8,0x3D,0x17,0xDB,0x1E,0xF8,0x9D,0xFF,0x43,0x26,0x19,0x84,0x65,0x83,0x24,0x00,0x00,0x00,0x00,0x00,
0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x02,0x1B,0x71,0x43,0x95,0x00,0x10,0x83,0x6E,0xFF,0x60,0xFD,0xE0,0x05,0x8F,0x4F,0x93,0x6B,0x3C,0x4A,
0xD3,0xF4,0x85,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
byte[] asm22 = new byte[asm22p1.Length + asm22p2.Length + asm22p3.Length + asm22p4.Length + asm22p5.Length + qq.token.Length];
//写入part 1
asm22p1.CopyTo(asm22, 0);
asm22p2.CopyTo(asm22, asm22p1.Length);
//写入part 2
asm22p3.CopyTo(asm22, asm22p1.Length + asm22p2.Length);
//写入part 3
asm22p4.CopyTo(asm22, asm22p1.Length + asm22p2.Length + asm22p3.Length);
//写入part 4
qq.token.CopyTo(asm22, asm22p1.Length + asm22p2.Length + asm22p3.Length + asm22p4.Length);
//写入part 5
asm22p5.CopyTo(asm22, asm22p1.Length + asm22p2.Length + asm22p3.Length + asm22p4.Length + qq.token.Length);
//加密为密文
byte[] tmp22 = cipher.QQ_Encrypt(asm22, qq.tmpkey);
bytes = new byte[tmp22.Length + 14 + qq.dd422.Length];
FillHead(bcommand);
byte[] lenofdd = { 0x00, 0x38 };
lenofdd.CopyTo(bytes, 11);
qq.dd422.CopyTo(bytes, 13);
tmp22.CopyTo(bytes, 13 + qq.dd422.Length);
break;
}
//追加报尾
bytes.SetValue(bptail, bytes.Length - 1);
}
}
class inpacket
{...}
}