stresser/
stresser.rs

1use std::io::{self, ErrorKind};
2use std::net::SocketAddr;
3
4use anyhow::bail;
5use tokio::io::AsyncWriteExt;
6use tokio::net::TcpStream;
7use uuid::Uuid;
8use valence_protocol::packets::handshaking::handshake_c2s::HandshakeNextState;
9use valence_protocol::packets::handshaking::HandshakeC2s;
10use valence_protocol::packets::login::{
11    LoginCompressionS2c, LoginHelloC2s, LoginHelloS2c, LoginSuccessS2c,
12};
13use valence_protocol::packets::play::{
14    KeepAliveC2s, KeepAliveS2c, PlayerPositionLookS2c, PositionAndOnGroundC2s, TeleportConfirmC2s,
15};
16use valence_protocol::var_int::VarInt;
17use valence_protocol::{
18    CompressionThreshold, Packet, PacketDecoder, PacketEncoder, PROTOCOL_VERSION,
19};
20
21pub struct SessionParams<'a> {
22    pub socket_addr: SocketAddr,
23    pub session_name: &'a str,
24    pub read_buffer_size: usize,
25}
26
27pub async fn make_session(params: &SessionParams<'_>) -> anyhow::Result<()> {
28    let sock_addr = params.socket_addr;
29    let sess_name = params.session_name;
30    let rb_size = params.read_buffer_size;
31
32    let mut conn = match TcpStream::connect(sock_addr).await {
33        Ok(conn) => {
34            println!("{sess_name} connected");
35            conn
36        }
37        Err(err) => {
38            eprintln!("{sess_name} connection failed");
39            return Err(err.into());
40        }
41    };
42
43    conn.set_nodelay(true)?;
44
45    let mut dec = PacketDecoder::new();
46    let mut enc = PacketEncoder::new();
47
48    let server_addr_str = sock_addr.ip().to_string();
49
50    let handshake_pkt = HandshakeC2s {
51        protocol_version: VarInt(PROTOCOL_VERSION),
52        server_address: server_addr_str.as_str().into(),
53        server_port: sock_addr.port(),
54        next_state: HandshakeNextState::Login,
55    };
56
57    enc.append_packet(&handshake_pkt)?;
58
59    enc.append_packet(&LoginHelloC2s {
60        username: sess_name.into(),
61        profile_id: Some(Uuid::new_v4()),
62    })?;
63
64    let write_buf = enc.take();
65    conn.write_all(&write_buf).await?;
66
67    loop {
68        dec.reserve(rb_size);
69
70        let mut read_buf = dec.take_capacity();
71
72        conn.readable().await?;
73
74        match conn.try_read_buf(&mut read_buf) {
75            Ok(0) => return Err(io::Error::from(ErrorKind::UnexpectedEof).into()),
76            Err(e) if e.kind() == io::ErrorKind::WouldBlock => continue,
77            Err(e) => return Err(e.into()),
78            Ok(_) => (),
79        };
80
81        dec.queue_bytes(read_buf);
82
83        if let Ok(Some(frame)) = dec.try_next_packet() {
84            match frame.id {
85                LoginCompressionS2c::ID => {
86                    let packet: LoginCompressionS2c = frame.decode()?;
87                    let threshold = packet.threshold.0;
88
89                    dec.set_compression(CompressionThreshold(threshold));
90                    enc.set_compression(CompressionThreshold(threshold));
91                }
92
93                LoginSuccessS2c::ID => {
94                    break;
95                }
96
97                LoginHelloS2c::ID => {
98                    bail!("encryption not implemented");
99                }
100
101                _ => (),
102            }
103        }
104    }
105
106    println!("{sess_name} logged in");
107
108    loop {
109        while let Some(frame) = dec.try_next_packet()? {
110            match frame.id {
111                KeepAliveS2c::ID => {
112                    let packet: KeepAliveS2c = frame.decode()?;
113                    enc.clear();
114
115                    enc.append_packet(&KeepAliveC2s { id: packet.id })?;
116                    conn.write_all(&enc.take()).await?;
117                }
118
119                PlayerPositionLookS2c::ID => {
120                    let packet: PlayerPositionLookS2c = frame.decode()?;
121                    enc.clear();
122
123                    enc.append_packet(&TeleportConfirmC2s {
124                        teleport_id: packet.teleport_id,
125                    })?;
126
127                    enc.append_packet(&PositionAndOnGroundC2s {
128                        position: packet.position,
129                        on_ground: true,
130                    })?;
131
132                    conn.write_all(&enc.take()).await?;
133                }
134                _ => (),
135            }
136        }
137
138        dec.reserve(rb_size);
139
140        let mut read_buf = dec.take_capacity();
141
142        conn.readable().await?;
143
144        match conn.try_read_buf(&mut read_buf) {
145            Ok(0) => return Err(io::Error::from(ErrorKind::UnexpectedEof).into()),
146            Err(e) if e.kind() == io::ErrorKind::WouldBlock => continue,
147            Err(e) => return Err(e.into()),
148            Ok(_) => (),
149        };
150
151        dec.queue_bytes(read_buf);
152    }
153}