mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
how do i do this
This commit is contained in:
parent
b6fb96429c
commit
3bd32cfa00
8 changed files with 261 additions and 150 deletions
51
Cargo.lock
generated
51
Cargo.lock
generated
|
@ -68,9 +68,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.0.1"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "azalea-auth"
|
name = "azalea-auth"
|
||||||
|
@ -104,6 +104,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"azalea-auth",
|
"azalea-auth",
|
||||||
"azalea-protocol",
|
"azalea-protocol",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -532,7 +533,7 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -596,7 +597,7 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
|
checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"socket2",
|
"socket2 0.3.19",
|
||||||
"widestring",
|
"widestring",
|
||||||
"winapi",
|
"winapi",
|
||||||
"winreg",
|
"winreg",
|
||||||
|
@ -640,9 +641,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.109"
|
version = "0.2.124"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"
|
checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
|
@ -652,10 +653,11 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.5"
|
version = "0.4.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
|
checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
"scopeguard",
|
"scopeguard",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -716,14 +718,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.7.14"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
|
checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"miow",
|
"miow",
|
||||||
"ntapi",
|
"ntapi",
|
||||||
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -842,6 +845,12 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oorandom"
|
name = "oorandom"
|
||||||
version = "11.1.3"
|
version = "11.1.3"
|
||||||
|
@ -1203,6 +1212,16 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.82"
|
version = "1.0.82"
|
||||||
|
@ -1270,16 +1289,18 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.15.0"
|
version = "1.18.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838"
|
checksum = "0f48b6d60512a392e34dbf7fd456249fd2de3c83669ab642e021903f4015185b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"libc",
|
"libc",
|
||||||
"memchr",
|
"memchr",
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
|
"once_cell",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"socket2 0.4.4",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
@ -1434,6 +1455,12 @@ version = "0.10.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.11.0+wasi-snapshot-preview1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.78"
|
version = "0.2.78"
|
||||||
|
|
18
README.md
18
README.md
|
@ -17,15 +17,15 @@ I named this Azalea because it sounds like a cool word and this is a cool librar
|
||||||
Note that this doesn't work yet, it's just how I want the API to look.
|
Note that this doesn't work yet, it's just how I want the API to look.
|
||||||
|
|
||||||
```rs
|
```rs
|
||||||
use azalea::{Bot, Event};
|
use azalea::{Account, Event};
|
||||||
|
|
||||||
let bot = Bot::offline("bot");
|
let account = Account::offline("bot");
|
||||||
// or let bot = azalea::Bot::microsoft("access token").await;
|
// or let account = azalea::Account::microsoft("access token").await;
|
||||||
|
|
||||||
bot.join("localhost".try_into().unwrap()).await.unwrap();
|
let bot = account.join("localhost".try_into().unwrap()).await.unwrap();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match bot.recv().await {
|
match bot.next().await {
|
||||||
Event::Message(m) {
|
Event::Message(m) {
|
||||||
if m.username == bot.username { return };
|
if m.username == bot.username { return };
|
||||||
bot.chat(m.message).await;
|
bot.chat(m.message).await;
|
||||||
|
@ -42,17 +42,17 @@ loop {
|
||||||
You can use the `azalea::Bots` struct to control many bots as one unit.
|
You can use the `azalea::Bots` struct to control many bots as one unit.
|
||||||
|
|
||||||
```rs
|
```rs
|
||||||
use azalea::{Bot, Bots, Event, pathfinder};
|
use azalea::{Account, Accounts, Event, pathfinder};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let bots = Bots::new();
|
let accounts = Accounts::new();
|
||||||
|
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
bots.add(Bot::offline(format!("bot{}", i)));
|
accounts.add(Account::offline(format!("bot{}", i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bots.join("localhost".try_into().unwrap()).await.unwrap();
|
let bots = accounts.join("localhost".try_into().unwrap()).await.unwrap();
|
||||||
|
|
||||||
bots.goto(pathfinder::GotoGoal(azalea::BlockCoord(0, 70, 0))).await;
|
bots.goto(pathfinder::GotoGoal(azalea::BlockCoord(0, 70, 0))).await;
|
||||||
|
|
||||||
|
|
|
@ -8,3 +8,4 @@ version = "0.1.0"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
azalea-auth = {path = "../azalea-auth"}
|
azalea-auth = {path = "../azalea-auth"}
|
||||||
azalea-protocol = {path = "../azalea-protocol"}
|
azalea-protocol = {path = "../azalea-protocol"}
|
||||||
|
tokio = {version = "1.18.0", features = ["sync"]}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Azalea Client
|
# Azalea Client
|
||||||
|
|
||||||
A library that can mimic everything a normal Minecraft client can do. If you want to make a bot, you should use `azalea` instead since it contains utilities for that.
|
A library that can mimic everything a normal Minecraft client can do. If you want to make a bot with higher-level functions, you should use `azalea` instead.
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
///! Connect to Minecraft servers.
|
|
||||||
use azalea_protocol::{
|
use azalea_protocol::{
|
||||||
connect::HandshakeConnection,
|
connect::{GameConnection, HandshakeConnection},
|
||||||
packets::{
|
packets::{
|
||||||
game::GamePacket,
|
game::GamePacket,
|
||||||
handshake::client_intention_packet::ClientIntentionPacket,
|
handshake::client_intention_packet::ClientIntentionPacket,
|
||||||
|
@ -12,140 +11,219 @@ use azalea_protocol::{
|
||||||
},
|
},
|
||||||
resolver, ServerAddress,
|
resolver, ServerAddress,
|
||||||
};
|
};
|
||||||
|
use futures::FutureExt;
|
||||||
|
use std::{
|
||||||
|
borrow::BorrowMut,
|
||||||
|
cell::RefCell,
|
||||||
|
future::Future,
|
||||||
|
pin::Pin,
|
||||||
|
sync::{Arc, Mutex, Weak},
|
||||||
|
};
|
||||||
|
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};
|
||||||
|
|
||||||
pub async fn join_server(address: &ServerAddress) -> Result<(), String> {
|
///! Connect to Minecraft servers.
|
||||||
let username = "bot".to_string();
|
|
||||||
|
|
||||||
let resolved_address = resolver::resolve_address(address).await?;
|
/// Something that can join Minecraft servers.
|
||||||
|
pub struct Account {
|
||||||
|
username: String,
|
||||||
|
}
|
||||||
|
|
||||||
let mut conn = HandshakeConnection::new(&resolved_address).await?;
|
pub struct ClientState {
|
||||||
|
// placeholder
|
||||||
|
pub health: u16,
|
||||||
|
}
|
||||||
|
|
||||||
// handshake
|
/// A player that you can control that is currently in a Minecraft server.
|
||||||
conn.write(
|
pub struct Client {
|
||||||
ClientIntentionPacket {
|
event_receiver: UnboundedReceiver<Event>,
|
||||||
protocol_version: PROTOCOL_VERSION,
|
conn: GameConnection,
|
||||||
hostname: address.host.clone(),
|
state: ClientState,
|
||||||
port: address.port,
|
}
|
||||||
intention: ConnectionProtocol::Login,
|
|
||||||
}
|
|
||||||
.get(),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
let mut conn = conn.login();
|
|
||||||
|
|
||||||
// login
|
pub enum Event {}
|
||||||
conn.write(ServerboundHelloPacket { username }.get()).await;
|
|
||||||
|
|
||||||
let mut conn = loop {
|
impl Client {
|
||||||
let packet_result = conn.read().await;
|
async fn join(account: &Account, address: &ServerAddress) -> Result<Arc<Mutex<Self>>, String> {
|
||||||
match packet_result {
|
let resolved_address = resolver::resolve_address(address).await?;
|
||||||
Ok(packet) => match packet {
|
|
||||||
LoginPacket::ClientboundHelloPacket(p) => {
|
|
||||||
println!("Got encryption request {:?} {:?}", p.nonce, p.public_key);
|
|
||||||
let e = azalea_auth::encryption::encrypt(&p.public_key, &p.nonce).unwrap();
|
|
||||||
|
|
||||||
// TODO: authenticate with the server here (authenticateServer)
|
let mut conn = HandshakeConnection::new(&resolved_address).await?;
|
||||||
println!("Sending encryption response {:?}", e);
|
|
||||||
|
|
||||||
conn.write(
|
// handshake
|
||||||
ServerboundKeyPacket {
|
conn.write(
|
||||||
nonce: e.encrypted_nonce.into(),
|
ClientIntentionPacket {
|
||||||
shared_secret: e.encrypted_public_key.into(),
|
protocol_version: PROTOCOL_VERSION,
|
||||||
}
|
hostname: address.host.clone(),
|
||||||
.get(),
|
port: address.port,
|
||||||
)
|
intention: ConnectionProtocol::Login,
|
||||||
.await;
|
|
||||||
conn.set_encryption_key(e.secret_key);
|
|
||||||
}
|
|
||||||
LoginPacket::ClientboundLoginCompressionPacket(p) => {
|
|
||||||
println!("Got compression request {:?}", p.compression_threshold);
|
|
||||||
conn.set_compression_threshold(p.compression_threshold);
|
|
||||||
}
|
|
||||||
LoginPacket::ClientboundGameProfilePacket(p) => {
|
|
||||||
println!("Got profile {:?}", p.game_profile);
|
|
||||||
break conn.game();
|
|
||||||
}
|
|
||||||
LoginPacket::ServerboundHelloPacket(p) => {
|
|
||||||
println!("Got hello {:?}", p);
|
|
||||||
}
|
|
||||||
LoginPacket::ClientboundLoginDisconnectPacket(p) => {
|
|
||||||
println!("Got disconnect {:?}", p);
|
|
||||||
}
|
|
||||||
LoginPacket::ClientboundCustomQueryPacket(p) => {
|
|
||||||
println!("Got custom query {:?}", p);
|
|
||||||
}
|
|
||||||
LoginPacket::ServerboundKeyPacket(_) => todo!(),
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
panic!("Error: {:?}", e);
|
|
||||||
}
|
}
|
||||||
}
|
.get(),
|
||||||
};
|
)
|
||||||
|
.await;
|
||||||
|
let mut conn = conn.login();
|
||||||
|
|
||||||
// game
|
// login
|
||||||
loop {
|
conn.write(
|
||||||
let packet_result = conn.read().await;
|
ServerboundHelloPacket {
|
||||||
match packet_result {
|
username: account.username.clone(),
|
||||||
Ok(packet) => match packet {
|
}
|
||||||
GamePacket::ClientboundLoginPacket(p) => {
|
.get(),
|
||||||
println!("Got login packet {:?}", p);
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
let conn = loop {
|
||||||
|
let packet_result = conn.read().await;
|
||||||
|
match packet_result {
|
||||||
|
Ok(packet) => match packet {
|
||||||
|
LoginPacket::ClientboundHelloPacket(p) => {
|
||||||
|
println!("Got encryption request {:?} {:?}", p.nonce, p.public_key);
|
||||||
|
let e = azalea_auth::encryption::encrypt(&p.public_key, &p.nonce).unwrap();
|
||||||
|
|
||||||
|
// TODO: authenticate with the server here (authenticateServer)
|
||||||
|
println!("Sending encryption response {:?}", e);
|
||||||
|
|
||||||
|
conn.write(
|
||||||
|
ServerboundKeyPacket {
|
||||||
|
nonce: e.encrypted_nonce.into(),
|
||||||
|
shared_secret: e.encrypted_public_key.into(),
|
||||||
|
}
|
||||||
|
.get(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
conn.set_encryption_key(e.secret_key);
|
||||||
|
}
|
||||||
|
LoginPacket::ClientboundLoginCompressionPacket(p) => {
|
||||||
|
println!("Got compression request {:?}", p.compression_threshold);
|
||||||
|
conn.set_compression_threshold(p.compression_threshold);
|
||||||
|
}
|
||||||
|
LoginPacket::ClientboundGameProfilePacket(p) => {
|
||||||
|
println!("Got profile {:?}", p.game_profile);
|
||||||
|
break conn.game();
|
||||||
|
}
|
||||||
|
LoginPacket::ServerboundHelloPacket(p) => {
|
||||||
|
println!("Got hello {:?}", p);
|
||||||
|
}
|
||||||
|
LoginPacket::ClientboundLoginDisconnectPacket(p) => {
|
||||||
|
println!("Got disconnect {:?}", p);
|
||||||
|
}
|
||||||
|
LoginPacket::ClientboundCustomQueryPacket(p) => {
|
||||||
|
println!("Got custom query {:?}", p);
|
||||||
|
}
|
||||||
|
LoginPacket::ServerboundKeyPacket(_) => todo!(),
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
panic!("Error: {:?}", e);
|
||||||
}
|
}
|
||||||
GamePacket::ClientboundUpdateViewDistancePacket(p) => {
|
}
|
||||||
println!("Got view distance packet {:?}", p);
|
};
|
||||||
}
|
|
||||||
GamePacket::ClientboundCustomPayloadPacket(p) => {
|
let (tx, rx) = mpsc::unbounded_channel();
|
||||||
println!("Got custom payload packet {:?}", p);
|
|
||||||
}
|
// we got the GameConnection, so the server is now connected :)
|
||||||
GamePacket::ClientboundChangeDifficultyPacket(p) => {
|
let client = Client {
|
||||||
println!("Got difficulty packet {:?}", p);
|
event_receiver: rx,
|
||||||
}
|
conn,
|
||||||
GamePacket::ClientboundDeclareCommandsPacket(p) => {
|
state: ClientState { health: 20 },
|
||||||
println!("Got declare commands packet");
|
};
|
||||||
}
|
// let client = Arc::new(Mutex::new(client));
|
||||||
GamePacket::ClientboundPlayerAbilitiesPacket(p) => {
|
// let weak_client = Arc::<_>::downgrade(&client);
|
||||||
println!("Got player abilities packet {:?}", p);
|
|
||||||
}
|
// just start up the game loop and we're ready!
|
||||||
GamePacket::ClientboundSetCarriedItemPacket(p) => {
|
// tokio::spawn(Self::game_loop(weak_client, tx));
|
||||||
println!("Got set carried item packet {:?}", p);
|
|
||||||
}
|
Ok(client)
|
||||||
GamePacket::ClientboundUpdateTagsPacket(p) => {
|
}
|
||||||
println!("Got update tags packet");
|
|
||||||
}
|
// async fn game_loop(weak_client: Weak<Mutex<Client>>, tx: UnboundedSender<Event>) {
|
||||||
GamePacket::ClientboundDisconnectPacket(p) => {
|
// loop {
|
||||||
println!("Got login disconnect packet {:?}", p);
|
// let client_option = weak_client.upgrade();
|
||||||
}
|
// match client_option {
|
||||||
GamePacket::ClientboundUpdateRecipesPacket(p) => {
|
// Some(client) => {
|
||||||
println!("Got update recipes packet");
|
// let mut client = client.lock().unwrap();
|
||||||
}
|
|
||||||
GamePacket::ClientboundEntityEventPacket(p) => {
|
// match client.conn.read().await {
|
||||||
println!("Got entity event packet {:?}", p);
|
// Ok(packet) => client.handle(&packet, &tx),
|
||||||
}
|
// Err(e) => {
|
||||||
GamePacket::ClientboundRecipePacket(p) => {
|
// panic!("Error: {:?}", e);
|
||||||
println!("Got recipe packet");
|
// }
|
||||||
}
|
// };
|
||||||
GamePacket::ClientboundPlayerPositionPacket(p) => {
|
// }
|
||||||
// TODO: reply with teleport confirm
|
// // the client was dropped, so we're done
|
||||||
println!("Got player position packet {:?}", p);
|
// None => break,
|
||||||
}
|
// }
|
||||||
GamePacket::ClientboundPlayerInfoPacket(p) => {
|
// }
|
||||||
println!("Got player info packet {:?}", p);
|
// }
|
||||||
}
|
|
||||||
GamePacket::ClientboundSetChunkCacheCenterPacket(p) => {
|
fn handle(&self, packet: &GamePacket, tx: &UnboundedSender<Event>) {
|
||||||
println!("Got chunk cache center packet {:?}", p);
|
match packet {
|
||||||
}
|
GamePacket::ClientboundLoginPacket(p) => {
|
||||||
GamePacket::ClientboundLevelChunkWithLightPacket(p) => {
|
println!("Got login packet {:?}", p);
|
||||||
println!("Got chunk with light packet");
|
}
|
||||||
}
|
GamePacket::ClientboundUpdateViewDistancePacket(p) => {
|
||||||
GamePacket::ClientboundLightUpdatePacket(p) => {
|
println!("Got view distance packet {:?}", p);
|
||||||
println!("Got light update packet {:?}", p);
|
}
|
||||||
}
|
GamePacket::ClientboundCustomPayloadPacket(p) => {
|
||||||
},
|
println!("Got custom payload packet {:?}", p);
|
||||||
Err(e) => {
|
}
|
||||||
panic!("Error: {:?}", e);
|
GamePacket::ClientboundChangeDifficultyPacket(p) => {
|
||||||
|
println!("Got difficulty packet {:?}", p);
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundDeclareCommandsPacket(p) => {
|
||||||
|
println!("Got declare commands packet");
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundPlayerAbilitiesPacket(p) => {
|
||||||
|
println!("Got player abilities packet {:?}", p);
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundSetCarriedItemPacket(p) => {
|
||||||
|
println!("Got set carried item packet {:?}", p);
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundUpdateTagsPacket(p) => {
|
||||||
|
println!("Got update tags packet");
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundDisconnectPacket(p) => {
|
||||||
|
println!("Got login disconnect packet {:?}", p);
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundUpdateRecipesPacket(p) => {
|
||||||
|
println!("Got update recipes packet");
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundEntityEventPacket(p) => {
|
||||||
|
println!("Got entity event packet {:?}", p);
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundRecipePacket(p) => {
|
||||||
|
println!("Got recipe packet");
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundPlayerPositionPacket(p) => {
|
||||||
|
// TODO: reply with teleport confirm
|
||||||
|
println!("Got player position packet {:?}", p);
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundPlayerInfoPacket(p) => {
|
||||||
|
println!("Got player info packet {:?}", p);
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundSetChunkCacheCenterPacket(p) => {
|
||||||
|
println!("Got chunk cache center packet {:?}", p);
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundLevelChunkWithLightPacket(p) => {
|
||||||
|
println!("Got chunk with light packet");
|
||||||
|
}
|
||||||
|
GamePacket::ClientboundLightUpdatePacket(p) => {
|
||||||
|
println!("Got light update packet {:?}", p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
pub async fn next(&mut self) -> Option<Event> {
|
||||||
|
self.event_receiver.recv().await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Account {
|
||||||
|
pub fn offline(username: &str) -> Self {
|
||||||
|
Self {
|
||||||
|
username: username.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn join(&self, address: &ServerAddress) -> Result<Arc<Mutex<Client>>, String> {
|
||||||
|
Client::join(&self, address).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
//! Significantly abstract azalea-protocol so it's actually useable for bots.
|
//! Significantly abstract azalea-protocol so it's actually useable for bots.
|
||||||
|
|
||||||
pub mod connect;
|
mod connect;
|
||||||
pub mod ping;
|
pub mod ping;
|
||||||
|
|
||||||
|
pub use connect::{Account, ServerClient};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub struct ClientboundLevelChunkWithLightPacket {
|
||||||
#[derive(Clone, Debug, McBufReadable, McBufWritable)]
|
#[derive(Clone, Debug, McBufReadable, McBufWritable)]
|
||||||
pub struct ClientboundLevelChunkPacketData {
|
pub struct ClientboundLevelChunkPacketData {
|
||||||
heightmaps: azalea_nbt::Tag,
|
heightmaps: azalea_nbt::Tag,
|
||||||
|
// we can't parse the data in azalea-protocol because it dependso on context from other packets
|
||||||
data: Vec<u8>,
|
data: Vec<u8>,
|
||||||
block_entities: Vec<BlockEntity>,
|
block_entities: Vec<BlockEntity>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,17 @@ async fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
|
|
||||||
// let address = "95.111.249.143:10000";
|
// let address = "95.111.249.143:10000";
|
||||||
// let address = "localhost:52467";
|
let address = "localhost:53193";
|
||||||
let address = "localhost:25566";
|
|
||||||
// let response = azalea_client::ping::ping_server(&address.try_into().unwrap())
|
// let response = azalea_client::ping::ping_server(&address.try_into().unwrap())
|
||||||
// .await
|
// .await
|
||||||
// .unwrap();
|
// .unwrap();
|
||||||
|
|
||||||
// println!("{}", response.description.to_ansi(None));
|
// println!("{}", response.description.to_ansi(None));
|
||||||
let _response = azalea_client::connect::join_server(&address.try_into().unwrap())
|
let account = azalea_client::Account::offline("bot");
|
||||||
.await
|
let client = account.join(&address.try_into().unwrap()).await.unwrap();
|
||||||
.unwrap();
|
|
||||||
println!("connected");
|
println!("connected");
|
||||||
|
|
||||||
|
// loop {
|
||||||
|
// match client.next().await {}
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue