pozk_utils/
p2p.rs

1pub use ethers::types::Address;
2use std::str::FromStr;
3
4const POZK_PLAYER_BINARY: [u8; 8] = [112, 111, 122, 107, 58, 0, 6, 58]; // "pozk:06:"
5
6pub enum TextMessage {
7    Started,
8    Over,
9    ConnectPlayer(Address, String),
10    ConnectViewer(Address),
11    ClosePlayer(Address),
12    CloseViewer(Address),
13    Player(Address, String),
14    Broadcast(String),
15}
16
17pub enum BinaryMessage {
18    Player(Address, Vec<u8>),
19    Broadcast(Vec<u8>),
20}
21
22impl TextMessage {
23    pub fn encode(self) -> String {
24        match self {
25            TextMessage::Started => "pozk:00:".to_owned(),
26            TextMessage::Over => "pozk:01:".to_owned(),
27            TextMessage::ConnectPlayer(peer, text) => format!("pozk:02:{:?}:{}", peer, text),
28            TextMessage::ConnectViewer(peer) => format!("pozk:03:{:?}", peer),
29            TextMessage::ClosePlayer(peer) => format!("pozk:04:{:?}", peer),
30            TextMessage::CloseViewer(peer) => format!("pozk:05:{:?}", peer),
31            TextMessage::Player(peer, text) => format!("pozk:06:{:?}:{}", peer, text),
32            TextMessage::Broadcast(text) => text,
33        }
34    }
35
36    pub fn decode(mut text: String) -> TextMessage {
37        if text.len() < 8 {
38            return TextMessage::Broadcast(text);
39        }
40        let dp = Address::zero();
41        let real = text.split_off(8);
42        match text.as_str() {
43            "pozk:00:" => TextMessage::Started,
44            "pozk:01:" => TextMessage::Over,
45            "pozk:02:" => {
46                let mut info = real.split(":");
47                let addr = info.next().unwrap_or("");
48                let text = info.next().unwrap_or("");
49                let peer = Address::from_str(&addr).unwrap_or(dp);
50                TextMessage::ConnectPlayer(peer, text.to_owned())
51            }
52            "pozk:03:" => TextMessage::ConnectViewer(Address::from_str(&real).unwrap_or(dp)),
53            "pozk:04:" => TextMessage::ClosePlayer(Address::from_str(&real).unwrap_or(dp)),
54            "pozk:05:" => TextMessage::CloseViewer(Address::from_str(&real).unwrap_or(dp)),
55            "pozk:06:" => {
56                if real.len() < 43 {
57                    TextMessage::Broadcast(text + &real)
58                } else {
59                    let peer = Address::from_str(&real[0..42]).unwrap_or(dp);
60                    TextMessage::Player(peer, real[43..].to_owned())
61                }
62            }
63            _ => TextMessage::Broadcast(text + &real),
64        }
65    }
66}
67
68impl BinaryMessage {
69    pub fn encode(self) -> Vec<u8> {
70        match self {
71            BinaryMessage::Player(peer, data) => {
72                let mut new_data = POZK_PLAYER_BINARY.to_vec(); // 8
73                new_data.extend(peer.to_fixed_bytes()); // 20
74                new_data.push(58); // ":" 1
75                new_data.extend(data);
76                new_data
77            }
78            BinaryMessage::Broadcast(data) => data,
79        }
80    }
81
82    pub fn decode(mut data: Vec<u8>) -> BinaryMessage {
83        if data.len() > 28 && &data[0..8] == &POZK_PLAYER_BINARY {
84            let peer = Address::from_slice(&data[8..28]);
85            let real = data.split_off(29);
86            BinaryMessage::Player(peer, real)
87        } else {
88            BinaryMessage::Broadcast(data)
89        }
90    }
91}