raknet_rust/protocol/
connected.rs1use 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}