ghast_client/lib.rs
1//! Headless Minecraft Java Edition client for the ghast library.
2//!
3//! - [`Client`]: connect (directly or through a SOCKS5 proxy, see [`ghast_auth::connect`]),
4//! handshake, login (offline; online mode with the `microsoft` feature), compression and
5//! encryption, then the play state: keep-alives, teleports, window confirms, health,
6//! respawn, chat.
7//! - A fixed 50 ms tick loop with vanilla 1.8.9's tick order (see [`engine`](crate::TickContext)
8//! for the details): inbound packets → [`Behavior::tick`] (actions written immediately) →
9//! rotation → movement → exactly one movement packet.
10//! - A version-agnostic API: behaviours see [`TickContext`] and the types of [`common`],
11//! never packets. The connection is generic over the protocol version
12//! ([`version::ClientVersion`]), so each supported version is monomorphised.
13//! - Packets nobody needs are dropped before they are decoded; a behaviour opts into more
14//! with [`Behavior::interests`].
15//!
16//! Supported versions: 1.8.9 (protocol 47) and 1.16.5 (protocol 754).
17//!
18//! ```no_run
19//! use ghast_client::{Account, Behavior, Client, GameVersion, Interests, TickContext};
20//!
21//! struct Echo;
22//! impl Behavior for Echo {
23//! fn interests(&self) -> Interests {
24//! Interests::CHAT
25//! }
26//! fn tick(&mut self, ctx: &mut TickContext<'_>) {
27//! let lines: Vec<String> = ctx.events().chat.iter().map(|m| m.plain()).collect();
28//! for line in lines {
29//! println!("chat: {line}");
30//! }
31//! if ctx.is_dead() {
32//! ctx.respawn();
33//! }
34//! }
35//! }
36//!
37//! # async fn run() -> Result<(), Box<dyn std::error::Error>> {
38//! let client = Client::new("localhost:25565".parse()?, GameVersion::V1_8_9, Account::offline("Steve")?);
39//! let end = client.run(&mut Echo).await?;
40//! println!("session ended: {end:?}");
41//! # Ok(())
42//! # }
43//! ```
44
45#![forbid(unsafe_code)]
46#![warn(missing_docs, rust_2018_idioms, unreachable_pub)]
47
48mod client;
49pub mod common;
50mod engine;
51mod error;
52pub mod hands;
53mod interest;
54pub mod movement;
55mod record;
56pub mod rotation;
57mod sim;
58#[cfg(test)]
59mod trace_replay;
60pub mod version;
61
62pub use client::{Account, Client, TICK};
63pub use common::{ChatMessage, ClientSettings, Controls, Face, GameMode, Health, Pose, Vec3};
64pub use engine::{Behavior, ClickRefused, ClickTicket, Idle, RawInbound, TickContext, TickEvents};
65pub use error::{ClientError, SessionEnd};
66pub use ghast_entity as entity;
67pub use ghast_inventory as inventory;
68pub use ghast_protocol::BlockPos;
69pub use ghast_world as world;
70pub use hands::{BlockHit, Buttons};
71pub use interest::Interests;
72pub use sim::{ForceStepPosition, WorldView};
73pub use version::GameVersion;
74
75/// Re-exports of the connection setup types from `ghast-auth`.
76pub mod connect {
77 pub use ghast_auth::connect::{
78 ConnectError, Connector, ProxyPolicy, Route, TargetAddr, Timeouts,
79 };
80 pub use ghast_auth::socks5::Socks5Proxy;
81}