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
|
use crate::{friendly_byte_buf::FriendlyByteBuf, packets::Packet, ServerIpAddress};
use bytes::BytesMut;
use tokio::{
io::{AsyncWriteExt, BufWriter},
net::TcpStream,
};
pub enum PacketFlow {
ClientToServer,
ServerToClient,
}
pub struct Connection {
pub flow: PacketFlow,
pub stream: BufWriter<TcpStream>,
/// The read buffer
pub buffer: BytesMut,
}
impl Connection {
pub async fn new(address: &ServerIpAddress) -> Result<Connection, String> {
let ip = address.ip;
let port = address.port;
let stream = TcpStream::connect(format!("{}:{}", ip, port))
.await
.map_err(|_| "Failed to connect to server")?;
// enable tcp_nodelay
stream
.set_nodelay(true)
.expect("Error enabling tcp_nodelay");
Ok(Connection {
flow: PacketFlow::ClientToServer,
stream: BufWriter::new(stream),
// 4mb read buffer
buffer: BytesMut::with_capacity(4 * 1024 * 1024),
})
}
/// Write a packet to the server
pub async fn send_packet(&mut self, packet: &dyn Packet) {
// packet structure:
// length + id + data
// Is this efficient? I have no idea, probably not.
// getting rid of the FriendlyByteBuffer struct might help
// write the packet id
let mut id_and_data_buf = vec![packet.get_id()];
// write the packet data
let mut id_and_data_friendly_buf = FriendlyByteBuf::new(&mut id_and_data_buf);
packet.write(&mut id_and_data_friendly_buf);
// add the packet length to the beginning
let mut complete_buf: Vec<u8> = Vec::new();
let mut complete_friendly_buf = FriendlyByteBuf::new(&mut complete_buf);
complete_friendly_buf.write_varint(id_and_data_buf.len() as u32);
complete_buf.append(&mut id_and_data_buf);
// finally, write and flush to the stream
self.stream.write_all(&complete_buf).await.unwrap();
self.stream.flush().await.unwrap();
}
}
|