1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use crate::crypto::qqtea_encrypt;
use crate::hex::decode_hex;
use bytes::{Buf, BufMut, BytesMut};
pub trait BinaryWriter {
fn write_bytes_short(&mut self, data: &[u8]);
fn encrypt_and_write(&mut self, key: &[u8], data: &[u8]);
fn write_hex(&mut self, h: &str);
fn write_int_lv_packet(&mut self, offset: usize, data: &[u8]);
fn write_string(&mut self, v: &str);
fn write_uni_packet(
&mut self,
command_name: &str,
session_id: &[u8],
extra_data: &[u8],
body: &[u8],
);
fn write_tlv_limited_size(&mut self, data: &[u8], limit: isize);
}
impl<B> BinaryWriter for B
where
B: BufMut,
{
fn write_bytes_short(&mut self, data: &[u8]) {
self.put_u16(data.len() as u16);
self.put_slice(data.chunk())
}
fn encrypt_and_write(&mut self, key: &[u8], data: &[u8]) {
let ed = qqtea_encrypt(data, key);
self.put_slice(&ed)
}
fn write_hex(&mut self, h: &str) {
let b = decode_hex(h).expect("write_hex failed");
self.put_slice(&b);
}
fn write_int_lv_packet(&mut self, offset: usize, data: &[u8]) {
self.put_u32((data.len() + offset) as u32);
self.put_slice(data);
}
fn write_string(&mut self, v: &str) {
let payload = v.as_bytes();
self.put_u32((payload.len() + 4) as u32);
self.put_slice(payload)
}
fn write_uni_packet(
&mut self,
command_name: &str,
session_id: &[u8],
extra_data: &[u8],
body: &[u8],
) {
let mut w1 = BytesMut::new();
{
w1.write_string(command_name);
w1.put_u32(8);
w1.put_slice(session_id);
if extra_data.is_empty() {
w1.put_u32(0x04)
} else {
w1.put_u32((extra_data.len() + 4) as u32);
w1.put_slice(extra_data);
}
}
self.put_u32((w1.len() + 4) as u32);
self.put_slice(&w1);
self.put_u32((body.len() + 4) as u32);
self.put_slice(body);
}
fn write_tlv_limited_size(&mut self, data: &[u8], limit: isize) {
if data.len() <= limit as usize {
self.write_bytes_short(data);
return;
}
self.write_bytes_short(&data[..(limit as usize)])
}
}