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}