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