1use std::io;
2
3use nurtex_protocol::connection::utils::handle_encryption_request;
4use nurtex_protocol::connection::{ConnectionState, NurtexConnection};
5use nurtex_protocol::packets::configuration::{
6 ClientsideConfigurationPacket, ServersideAcknowledgeFinishConfiguration, ServersideClientInformation, ServersideConfigurationPacket, ServersideKnownPacks,
7 ServersideResourcePackResponse,
8};
9use nurtex_protocol::packets::handshake::{ServersideGreet, ServersideHandshakePacket};
10use nurtex_protocol::packets::login::{ClientsideLoginPacket, ServersideLoginAcknowledged, ServersideLoginPacket, ServersideLoginStart};
11use nurtex_protocol::packets::play::{ClientsidePlayPacket, ServersidePlayPacket};
12use nurtex_protocol::types::{AccurateHand, ChatMode, ClientIntention, DisplayedSkinParts, ParticleStatus, ResourcePackState};
13
14#[tokio::main]
15async fn main() -> io::Result<()> {
16 let target_host = "locahost".to_string();
17 let target_port = 25565;
18
19 let conn = match NurtexConnection::new(&target_host, 25565).await {
21 Ok(c) => c,
22 Err(_) => return Ok(()),
23 };
24
25 conn
27 .write_handshake_packet(ServersideHandshakePacket::Greet(ServersideGreet {
28 protocol_version: 774, server_host: target_host,
30 server_port: target_port,
31 intention: ClientIntention::Login,
32 }))
33 .await?;
34
35 conn.set_state(ConnectionState::Login).await;
37
38 conn
40 .write_login_packet(ServersideLoginPacket::LoginStart(ServersideLoginStart {
41 username: "NurtexBot".to_string(),
42 uuid: uuid::Uuid::nil(),
43 }))
44 .await?;
45
46 loop {
48 if let Some(p) = conn.read_login_packet().await {
49 match p {
50 ClientsideLoginPacket::Compression(p) => {
51 conn.set_compression_threshold(p.compression_threshold).await;
53 }
54 ClientsideLoginPacket::EncryptionRequest(request) => {
55 if let Some((response, secret_key)) = handle_encryption_request(&request) {
57 conn.write_login_packet(ServersideLoginPacket::EncryptionResponse(response)).await?;
58 conn.set_encryption_key(secret_key).await;
59 }
60 }
61 ClientsideLoginPacket::LoginSuccess(_p) => {
62 conn.write_login_packet(ServersideLoginPacket::LoginAcknowledged(ServersideLoginAcknowledged)).await?;
64 break;
65 }
66 _ => {}
67 }
68 } else {
69 break;
70 }
71 }
72
73 conn.set_state(ConnectionState::Configuration).await;
75
76 conn
78 .write_configuration_packet(ServersideConfigurationPacket::ClientInformation(ServersideClientInformation {
79 locale: "en_US".to_string(),
80 view_distance: 10,
81 chat_mode: ChatMode::Enabled,
82 chat_colors: true,
83 displayed_skin_parts: DisplayedSkinParts::default(),
84 main_hand: AccurateHand::Right,
85 enable_text_filtering: false,
86 allow_server_listings: true,
87 particle_status: ParticleStatus::Minimal,
88 }))
89 .await?;
90
91 loop {
93 if let Some(p) = conn.read_configuration_packet().await {
94 match p {
95 ClientsideConfigurationPacket::KeepAlive(p) => {
96 conn
98 .write_configuration_packet(ServersideConfigurationPacket::KeepAlive(nurtex_protocol::packets::configuration::MultisideKeepAlive {
99 id: p.id,
100 }))
101 .await?;
102 }
103 ClientsideConfigurationPacket::Ping(p) => {
104 conn
106 .write_configuration_packet(ServersideConfigurationPacket::Pong(nurtex_protocol::packets::configuration::ServersidePong { id: p.id }))
107 .await?;
108 }
109 ClientsideConfigurationPacket::KnownPacks(p) => {
110 conn
112 .write_configuration_packet(ServersideConfigurationPacket::KnownPacks(ServersideKnownPacks { known_packs: p.known_packs }))
113 .await?;
114 }
115 ClientsideConfigurationPacket::FinishConfiguration(_) => {
116 conn
118 .write_configuration_packet(ServersideConfigurationPacket::AcknowledgeFinishConfiguration(ServersideAcknowledgeFinishConfiguration))
119 .await?;
120 break;
121 }
122 ClientsideConfigurationPacket::AddResourcePack(p) => {
123 conn
125 .write_configuration_packet(ServersideConfigurationPacket::ResourcePackResponse(ServersideResourcePackResponse {
126 uuid: p.uuid,
127 state: ResourcePackState::Accepted,
128 }))
129 .await?;
130 }
131 _ => {}
132 }
133 } else {
134 break;
135 }
136 }
137
138 conn.set_state(ConnectionState::Play).await;
140
141 loop {
143 if let Some(p) = conn.read_play_packet().await {
144 match p {
145 ClientsidePlayPacket::KeepAlive(p) => {
146 conn
148 .write_play_packet(ServersidePlayPacket::KeepAlive(nurtex_protocol::packets::play::MultisideKeepAlive { id: p.id }))
149 .await?;
150 }
151 ClientsidePlayPacket::Ping(p) => {
152 conn
154 .write_play_packet(ServersidePlayPacket::Pong(nurtex_protocol::packets::play::ServersidePong { id: p.id }))
155 .await?;
156 }
157 _ => {}
158 }
159 }
160 }
161}