Skip to main content

bancho_packet/packets/
reader.rs

1use crate::buffer::serialization::{Buffer, BytesExt, BytesMutExt};
2use crate::packets::structures;
3use bytes::{Buf, Bytes, BytesMut};
4
5// TODO: Use `thiserror`  cos macros are fun
6#[derive(Debug)]
7pub enum ParseError {
8    BadUTF8,
9}
10
11// TODO: This doesnt need to copy, could just slice into the buf
12#[derive(Debug, Clone)]
13pub struct LoginData {
14    pub username: String,
15    pub password_md5: String,
16    pub client_version: String,
17    pub utc_offset: i32,
18    pub show_city: i32,
19    pub allow_pms: i32,
20    pub path_md5: String,
21    pub adapters_string: String,
22    pub adapters_md5: String,
23    pub uninstall_md5: String,
24    pub disk_signature_md5: String,
25}
26
27impl LoginData {
28    pub fn from_slice(buf: &mut Bytes) -> Result<Self, ParseError> {
29        let username = String::from_utf8(buf.take_while(|b| b != b'\n').to_vec())
30            .map_err(|_| ParseError::BadUTF8)?;
31        buf.advance(1);
32
33        let password_md5 = String::from_utf8(buf.take_while(|b| b != b'\n').to_vec())
34            .map_err(|_| ParseError::BadUTF8)?;
35        buf.advance(1); // '\n'
36
37        let client_version = String::from_utf8(buf.take_while(|b| b != b'|').to_vec())
38            .map_err(|_| ParseError::BadUTF8)?;
39        buf.advance(1);
40
41        let utc_offset = String::from_utf8(buf.take_while(|b| b != b'|').to_vec())
42            .map_err(|_| ParseError::BadUTF8)?
43            .parse::<i32>()
44            .unwrap();
45        buf.advance(1);
46
47        let show_city = String::from_utf8(buf.take_while(|b| b != b'|').to_vec())
48            .map_err(|_| ParseError::BadUTF8)?
49            .parse::<i32>()
50            .unwrap();
51        buf.advance(1);
52
53        let client_hashes = String::from_utf8(buf.take_while(|b| b != b'|').to_vec())
54            .map_err(|_| ParseError::BadUTF8)?;
55        buf.advance(1);
56
57        let allow_pms = String::from_utf8(buf.take_while(|b| b != b'\n').to_vec())
58            .map_err(|_| ParseError::BadUTF8)?
59            .parse::<i32>()
60            .unwrap();
61        buf.advance(1);
62
63        let mut hashes_split = client_hashes.split(":").into_iter();
64
65        let path_md5 = hashes_split.next().unwrap().to_string();
66
67        let adapters_string = hashes_split.next().unwrap().to_string();
68
69        let adapters_md5 = hashes_split.next().unwrap().to_string();
70
71        let uninstall_md5 = hashes_split.next().unwrap().to_string();
72
73        let disk_signature_md5 = hashes_split.next().unwrap().to_string();
74
75        Ok(LoginData {
76            username,
77            password_md5,
78            client_version,
79            utc_offset,
80            show_city,
81            allow_pms,
82            path_md5,
83            adapters_string,
84            adapters_md5,
85            uninstall_md5,
86            disk_signature_md5,
87        })
88    }
89}
90
91pub fn client_send_mesage(buf: &mut Buffer) -> structures::BanchoMessage {
92    let sending_client = buf.get_string(); //buf.get_string();
93    let message = buf.get_string();
94    let target = buf.get_string();
95    let sender_id = buf.get_i32_le();
96
97    structures::BanchoMessage {
98        sending_client,
99        message,
100        target,
101        sender_id,
102    }
103}
104
105pub fn client_user_status(buf: &mut Buffer) -> structures::ClientStatus {
106    let status = buf.get_u8();
107    let status_text = buf.get_string();
108    let beatmap_checksum = buf.get_string();
109    let current_mods = buf.get_u32_le();
110    let play_mode = buf.get_u8();
111    let beatmap_id = buf.get_i32_le();
112    structures::ClientStatus {
113        status,
114        status_text,
115        beatmap_checksum,
116        current_mods,
117        play_mode,
118        beatmap_id,
119    }
120}