craftio_rs/
tcp.rs

1use crate::connection::CraftConnection;
2use crate::reader::CraftReader;
3use crate::writer::CraftWriter;
4use mcproto_rs::protocol::{PacketDirection, State};
5use std::io::BufReader as StdBufReader;
6use std::net::TcpStream;
7
8#[cfg(any(feature = "futures-io", feature = "tokio-io"))]
9use crate::{CraftAsyncReader, CraftAsyncWriter};
10
11#[cfg(feature = "tokio-io")]
12use tokio::{
13    net::{
14        TcpStream as TokioTcpStream,
15        tcp::{
16            OwnedReadHalf as TokioReadHalf,
17            OwnedWriteHalf as TokioWriteHalf,
18        },
19        ToSocketAddrs as TokioToSocketAddrs,
20    },
21    io::{
22        BufReader as TokioBufReader,
23        Error as TokioIoError,
24    },
25};
26
27pub const BUF_SIZE: usize = 8192;
28
29pub type CraftTcpConnection = CraftConnection<StdBufReader<TcpStream>, TcpStream>;
30
31impl CraftTcpConnection {
32    pub fn connect_server_std<A>(to: A) -> Result<Self, std::io::Error> where A: std::net::ToSocketAddrs {
33        Self::from_std(TcpStream::connect(to)?, PacketDirection::ClientBound)
34    }
35
36    pub fn wrap_client_stream_std(stream: TcpStream) -> Result<Self, std::io::Error> {
37        Self::from_std(stream, PacketDirection::ServerBound)
38    }
39
40    pub fn from_std(
41        s1: TcpStream,
42        read_direction: PacketDirection,
43    ) -> Result<Self, std::io::Error> {
44        Self::from_std_with_state(s1, read_direction, State::Handshaking)
45    }
46
47    pub fn from_std_with_state(
48        s1: TcpStream,
49        read_direction: PacketDirection,
50        state: State,
51    ) -> Result<Self, std::io::Error> {
52        let write = s1.try_clone()?;
53        let read = StdBufReader::with_capacity(BUF_SIZE, s1);
54
55        Ok(Self {
56            reader: CraftReader::wrap_with_state(read, read_direction, state),
57            writer: CraftWriter::wrap_with_state(write, read_direction.opposite(), state),
58        })
59    }
60}
61
62#[cfg(feature = "tokio-io")]
63pub type CraftTokioConnection = CraftConnection<TokioBufReader<TokioReadHalf>, TokioWriteHalf>;
64
65#[cfg(feature = "tokio-io")]
66impl CraftTokioConnection {
67    pub async fn connect_server_tokio<A>(
68        to: A
69    ) -> Result<Self, TokioIoError>
70    where
71        A: TokioToSocketAddrs
72    {
73        let conn = TokioTcpStream::connect(to).await?;
74        conn.set_nodelay(true)?;
75        let (reader, writer) = conn.into_split();
76        let reader = TokioBufReader::with_capacity(BUF_SIZE, reader);
77        Ok(Self::from_async((reader, writer), PacketDirection::ClientBound))
78    }
79}
80
81#[cfg(feature = "tokio-io")]
82pub type CraftUnbufferedTokioConnection = CraftConnection<TokioReadHalf, TokioWriteHalf>;
83
84#[cfg(feature = "tokio-io")]
85impl CraftUnbufferedTokioConnection {
86    pub async fn connect_server_tokio_unbuffered<A>(
87        to: A
88    ) -> Result<Self, TokioIoError>
89    where
90        A: TokioToSocketAddrs
91    {
92        let conn = TokioTcpStream::connect(to).await?;
93        conn.set_nodelay(true)?;
94
95        Ok(Self::from_async(
96            conn.into_split(),
97            PacketDirection::ClientBound,
98        ))
99    }
100}
101
102#[cfg(any(feature = "futures-io", feature = "tokio-io"))]
103impl<R, W> CraftConnection<R, W>
104where
105    CraftReader<R>: CraftAsyncReader,
106    CraftWriter<W>: CraftAsyncWriter,
107{
108    pub fn from_async(tuple: (R, W), read_direction: PacketDirection) -> Self {
109        Self::from_async_with_state(tuple, read_direction, State::Handshaking)
110    }
111
112    pub fn from_async_with_state(
113        tuple: (R, W),
114        read_direction: PacketDirection,
115        state: State,
116    ) -> Self {
117        let (reader, writer) = tuple;
118        Self {
119            reader: CraftReader::wrap_with_state(reader, read_direction, state),
120            writer: CraftWriter::wrap_with_state(writer, read_direction.opposite(), state),
121        }
122    }
123}