Skip to main content

raknet_rust/protocol/
connected.rs

1use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
2
3use bytes::{Buf, BufMut};
4
5use crate::error::{DecodeError, EncodeError};
6
7use super::codec::RaknetCodec;
8
9pub const SYSTEM_ADDRESS_COUNT: usize = 10;
10
11pub const ID_CONNECTED_PING: u8 = 0x00;
12pub const ID_CONNECTED_PONG: u8 = 0x03;
13pub const ID_CONNECTION_REQUEST: u8 = 0x09;
14pub const ID_CONNECTION_REQUEST_ACCEPTED: u8 = 0x10;
15pub const ID_NEW_INCOMING_CONNECTION: u8 = 0x13;
16pub const ID_DISCONNECTION_NOTIFICATION: u8 = 0x15;
17pub const ID_DETECT_LOST_CONNECTION: u8 = 0x04;
18
19#[derive(Debug, Clone)]
20pub struct ConnectedPing {
21    pub ping_time: i64,
22}
23
24#[derive(Debug, Clone)]
25pub struct ConnectedPong {
26    pub ping_time: i64,
27    pub pong_time: i64,
28}
29
30#[derive(Debug, Clone)]
31pub struct ConnectionRequest {
32    pub client_guid: u64,
33    pub request_time: i64,
34    pub use_encryption: bool,
35}
36
37#[derive(Debug, Clone)]
38pub struct ConnectionRequestAccepted {
39    pub client_addr: SocketAddr,
40    pub system_index: u16,
41    pub internal_addrs: [SocketAddr; SYSTEM_ADDRESS_COUNT],
42    pub request_time: i64,
43    pub accepted_time: i64,
44}
45
46#[derive(Debug, Clone)]
47pub struct NewIncomingConnection {
48    pub server_addr: SocketAddr,
49    pub internal_addrs: [SocketAddr; SYSTEM_ADDRESS_COUNT],
50    pub request_time: i64,
51    pub accepted_time: i64,
52}
53
54#[derive(Debug, Clone)]
55pub struct DisconnectionNotification {
56    pub reason: Option<u8>,
57}
58
59#[derive(Debug, Clone)]
60pub struct DetectLostConnection;
61
62#[derive(Debug, Clone)]
63pub enum ConnectedControlPacket {
64    ConnectedPing(ConnectedPing),
65    ConnectedPong(ConnectedPong),
66    ConnectionRequest(ConnectionRequest),
67    ConnectionRequestAccepted(ConnectionRequestAccepted),
68    NewIncomingConnection(NewIncomingConnection),
69    DisconnectionNotification(DisconnectionNotification),
70    DetectLostConnection(DetectLostConnection),
71}
72
73impl ConnectedControlPacket {
74    pub fn id(&self) -> u8 {
75        match self {
76            Self::ConnectedPing(_) => ID_CONNECTED_PING,
77            Self::ConnectedPong(_) => ID_CONNECTED_PONG,
78            Self::ConnectionRequest(_) => ID_CONNECTION_REQUEST,
79            Self::ConnectionRequestAccepted(_) => ID_CONNECTION_REQUEST_ACCEPTED,
80            Self::NewIncomingConnection(_) => ID_NEW_INCOMING_CONNECTION,
81            Self::DisconnectionNotification(_) => ID_DISCONNECTION_NOTIFICATION,
82            Self::DetectLostConnection(_) => ID_DETECT_LOST_CONNECTION,
83        }
84    }
85
86    pub fn encode(&self, dst: &mut impl BufMut) -> Result<(), EncodeError> {
87        self.id().encode_raknet(dst)?;
88        match self {
89            Self::ConnectedPing(pkt) => pkt.ping_time.encode_raknet(dst)?,
90            Self::ConnectedPong(pkt) => {
91                pkt.ping_time.encode_raknet(dst)?;
92                pkt.pong_time.encode_raknet(dst)?;
93            }
94            Self::ConnectionRequest(pkt) => {
95                pkt.client_guid.encode_raknet(dst)?;
96                pkt.request_time.encode_raknet(dst)?;
97                pkt.use_encryption.encode_raknet(dst)?;
98            }
99            Self::ConnectionRequestAccepted(pkt) => {
100                pkt.client_addr.encode_raknet(dst)?;
101                pkt.system_index.encode_raknet(dst)?;
102                for addr in &pkt.internal_addrs {
103                    addr.encode_raknet(dst)?;
104                }
105                pkt.request_time.encode_raknet(dst)?;
106                pkt.accepted_time.encode_raknet(dst)?;
107            }
108            Self::NewIncomingConnection(pkt) => {
109                pkt.server_addr.encode_raknet(dst)?;
110                for addr in &pkt.internal_addrs {
111                    addr.encode_raknet(dst)?;
112                }
113                pkt.request_time.encode_raknet(dst)?;
114                pkt.accepted_time.encode_raknet(dst)?;
115            }
116            Self::DisconnectionNotification(pkt) => {
117                if let Some(reason) = pkt.reason {
118                    reason.encode_raknet(dst)?;
119                }
120            }
121            Self::DetectLostConnection(_) => {}
122        }
123        Ok(())
124    }
125
126    pub fn decode(src: &mut impl Buf) -> Result<Self, DecodeError> {
127        let id = u8::decode_raknet(src)?;
128        match id {
129            ID_CONNECTED_PING => Ok(Self::ConnectedPing(ConnectedPing {
130                ping_time: i64::decode_raknet(src)?,
131            })),
132            ID_CONNECTED_PONG => Ok(Self::ConnectedPong(ConnectedPong {
133                ping_time: i64::decode_raknet(src)?,
134                pong_time: i64::decode_raknet(src)?,
135            })),
136            ID_CONNECTION_REQUEST => Ok(Self::ConnectionRequest(ConnectionRequest {
137                client_guid: u64::decode_raknet(src)?,
138                request_time: i64::decode_raknet(src)?,
139                use_encryption: bool::decode_raknet(src)?,
140            })),
141            ID_CONNECTION_REQUEST_ACCEPTED => {
142                let client_addr = SocketAddr::decode_raknet(src)?;
143                let system_index = u16::decode_raknet(src)?;
144                let mut internal_addrs = [default_socket_addr(); SYSTEM_ADDRESS_COUNT];
145                for item in &mut internal_addrs {
146                    *item = SocketAddr::decode_raknet(src)?;
147                }
148                let request_time = i64::decode_raknet(src)?;
149                let accepted_time = i64::decode_raknet(src)?;
150
151                Ok(Self::ConnectionRequestAccepted(ConnectionRequestAccepted {
152                    client_addr,
153                    system_index,
154                    internal_addrs,
155                    request_time,
156                    accepted_time,
157                }))
158            }
159            ID_NEW_INCOMING_CONNECTION => {
160                let server_addr = SocketAddr::decode_raknet(src)?;
161                let mut internal_addrs = [default_socket_addr(); SYSTEM_ADDRESS_COUNT];
162                for item in &mut internal_addrs {
163                    *item = SocketAddr::decode_raknet(src)?;
164                }
165                let request_time = i64::decode_raknet(src)?;
166                let accepted_time = i64::decode_raknet(src)?;
167
168                Ok(Self::NewIncomingConnection(NewIncomingConnection {
169                    server_addr,
170                    internal_addrs,
171                    request_time,
172                    accepted_time,
173                }))
174            }
175            ID_DISCONNECTION_NOTIFICATION => {
176                let reason = if src.has_remaining() {
177                    Some(u8::decode_raknet(src)?)
178                } else {
179                    None
180                };
181                Ok(Self::DisconnectionNotification(DisconnectionNotification {
182                    reason,
183                }))
184            }
185            ID_DETECT_LOST_CONNECTION => Ok(Self::DetectLostConnection(DetectLostConnection)),
186            _ => Err(DecodeError::InvalidConnectedPacketId(id)),
187        }
188    }
189}
190
191fn default_socket_addr() -> SocketAddr {
192    SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0))
193}