diff options
| author | mat <github@matdoes.dev> | 2022-04-29 20:22:26 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-04-29 20:22:26 -0500 |
| commit | baaa7658b58adfe72f0ea96d629dc76298ddf5dc (patch) | |
| tree | e07fd96cc07484ef771b1b5472d5dd7e1a92c847 | |
| parent | 3bd32cfa00e8b50b47267ab75a4ff8892ae89d54 (diff) | |
| parent | 8317b5b28153794770a8c7b84a1b6dd50eaa3f80 (diff) | |
| download | azalea-drasl-baaa7658b58adfe72f0ea96d629dc76298ddf5dc.tar.xz | |
Merge branch 'main' into chunk-packets
| -rwxr-xr-x | Cargo.lock | 31 | ||||
| -rwxr-xr-x | README.md | 51 | ||||
| -rwxr-xr-x | azalea-auth/Cargo.toml | 4 | ||||
| -rw-r--r-- | azalea-auth/src/encryption.rs | 30 | ||||
| -rwxr-xr-x | azalea-protocol/src/connect.rs | 27 | ||||
| -rwxr-xr-x | azalea-protocol/src/read.rs | 6 | ||||
| -rwxr-xr-x | azalea-protocol/src/write.rs | 14 | ||||
| -rw-r--r-- | bot/src/main.rs | 2 |
8 files changed, 114 insertions, 51 deletions
@@ -10,14 +10,13 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aes" -version = "0.7.5" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +checksum = "bfe0133578c0986e1fe3dfcd4af1cc5b2dd6c3dbf534d69916ce16a2701d40ba" dependencies = [ "cfg-if", "cipher", "cpufeatures", - "opaque-debug", ] [[package]] @@ -221,9 +220,9 @@ dependencies = [ [[package]] name = "cfb8" -version = "0.7.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a4b6c43bf284e617a659ce5dc149676680530a3a4a9bb6b278d1a9ed5b229d" +checksum = "014c0a0e1ad0dae6a86c082db2f9bd7fe8c2c734227047d0d8b4d4a3a094a1e1" dependencies = [ "cipher", ] @@ -246,11 +245,12 @@ dependencies = [ [[package]] name = "cipher" -version = "0.3.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +checksum = "d1873270f8f7942c191139cb8a40fd228da6c3fd2fc376d7e92d47aa14aeb59e" dependencies = [ - "generic-array", + "crypto-common", + "inout", ] [[package]] @@ -583,6 +583,15 @@ dependencies = [ ] [[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] name = "instant" version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -858,12 +867,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] -name = "opaque-debug" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" - -[[package]] name = "packet-macros" version = "0.1.0" dependencies = [ @@ -14,7 +14,7 @@ I named this Azalea because it sounds like a cool word and this is a cool librar ## Example code -Note that this doesn't work yet, it's just how I want the API to look. +Note that these doesn't work yet, it's just how I want the API to look. ```rs use azalea::{Account, Event}; @@ -39,6 +39,46 @@ loop { } ``` +```rs +use azalea::{Bot, Event}; + +let bot = Bot::offline("bot"); +// or let bot = azalea::Bot::microsoft("access token").await; + +bot.join("localhost".try_into().unwrap()).await.unwrap(); + +loop { + match bot.recv().await { + Event::Message(m) { + if m.username == bot.username { return }; + if m.message = "go" { + bot.goto_goal( + pathfinder::Goals::NearXZ(5, azalea::BlockXZ(0, 0)) + ).await; + let chest = bot.open_chest(&bot.world.find_one_block(|b| b.id == "minecraft:chest")).await.unwrap(); + bot.take_amount(&chest, 3, |i| i.id == "#minecraft:planks").await; + // when rust adds async drop this won't be necessary + chest.close().await; + + let crafting_table = bot.open_crafting_table(&bot.world.find_one_block(|b| b.id == "minecraft:crafting_table")).await.unwrap(); + bot.craft(&crafting_table, &bot.recipe_for("minecraft:sticks")).await?; + let pickaxe = bot.craft(&crafting_table, &bot.recipe_for("minecraft:wooden_pickaxe")).await?; + crafting_table.close().await; + + bot.hold(&pickaxe); + loop { + if let Err(e) = bot.dig(bot.feet_coords().down(1)).await { + println!("{:?}", e); + break; + } + } + } + }, + _ => {} + } +} +``` + You can use the `azalea::Bots` struct to control many bots as one unit. ```rs @@ -54,14 +94,15 @@ async fn main() { let bots = accounts.join("localhost".try_into().unwrap()).await.unwrap(); - bots.goto(pathfinder::GotoGoal(azalea::BlockCoord(0, 70, 0))).await; + bots.goto(azalea::BlockCoord(0, 70, 0)).await; + // or bots.goto_goal(pathfinder::Goals::Goto(azalea::BlockCoord(0, 70, 0))).await; // destroy the blocks in this area and then leave bots.fill( - pathfinder::FillGoal( - azalea::BlockCoord(-5, 60, -5), - azalea::BlockCoord(5, 70, 5) + azalea::Selection::Range( + azalea::BlockCoord(0, 0, 0), + azalea::BlockCoord(16, 255, 16) ), azalea::block::Air ).await; diff --git a/azalea-auth/Cargo.toml b/azalea-auth/Cargo.toml index 6279d903..5f62991b 100755 --- a/azalea-auth/Cargo.toml +++ b/azalea-auth/Cargo.toml @@ -6,8 +6,8 @@ version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -aes = "0.7.4" -cfb8 = "0.7.1" +aes = "0.8.1" +cfb8 = "0.8.1" num-bigint = "^0.4.3" rand = {version = "^0.8.4", features = ["getrandom"]} rsa_public_encrypt_pkcs1 = "0.4.0" diff --git a/azalea-auth/src/encryption.rs b/azalea-auth/src/encryption.rs index 6f2e43a8..dc2620cc 100644 --- a/azalea-auth/src/encryption.rs +++ b/azalea-auth/src/encryption.rs @@ -1,8 +1,11 @@ +use aes::cipher::inout::InOutBuf; +use aes::cipher::BlockEncrypt; use aes::{ - cipher::{AsyncStreamCipher, NewCipher}, + cipher::{ + generic_array::GenericArray, AsyncStreamCipher, BlockDecryptMut, BlockEncryptMut, KeyIvInit, + }, Aes128, }; -use cfb8::Cfb8; use rand::{rngs::OsRng, RngCore}; use sha1::{Digest, Sha1}; @@ -57,17 +60,26 @@ pub fn encrypt(public_key: &[u8], nonce: &[u8]) -> Result<EncryptResult, String> } // TODO: update the aes and cfb8 crates -pub type Aes128Cfb = Cfb8<Aes128>; +pub type Aes128CfbEnc = cfb8::Encryptor<Aes128>; +pub type Aes128CfbDec = cfb8::Decryptor<Aes128>; -pub fn create_cipher(key: &[u8]) -> Aes128Cfb { - Aes128Cfb::new_from_slices(&key, &key).unwrap() +pub fn create_cipher(key: &[u8]) -> (Aes128CfbEnc, Aes128CfbDec) { + ( + Aes128CfbEnc::new_from_slices(key, key).unwrap(), + Aes128CfbDec::new_from_slices(key, key).unwrap(), + ) } -pub fn encrypt_packet(cipher: &mut Aes128Cfb, packet: &mut [u8]) { - cipher.encrypt(packet); +// wow this is terrible +pub fn encrypt_packet(cipher: &mut Aes128CfbEnc, packet: &mut [u8]) { + let (chunks, rest) = InOutBuf::from(packet).into_chunks(); + assert!(rest.is_empty()); + cipher.encrypt_blocks_inout_mut(chunks); } -pub fn decrypt_packet(cipher: &mut Aes128Cfb, packet: &mut [u8]) { - cipher.decrypt(packet); +pub fn decrypt_packet(cipher: &mut Aes128CfbDec, packet: &mut [u8]) { + let (chunks, rest) = InOutBuf::from(packet).into_chunks(); + assert!(rest.is_empty()); + cipher.decrypt_blocks_inout_mut(chunks); } #[cfg(test)] diff --git a/azalea-protocol/src/connect.rs b/azalea-protocol/src/connect.rs index e81bc368..c55f2e90 100755 --- a/azalea-protocol/src/connect.rs +++ b/azalea-protocol/src/connect.rs @@ -7,7 +7,7 @@ use crate::packets::status::StatusPacket; use crate::read::read_packet; use crate::write::write_packet; use crate::ServerIpAddress; -use azalea_auth::encryption::Aes128Cfb; +use azalea_auth::encryption::{Aes128CfbDec, Aes128CfbEnc}; use tokio::net::TcpStream; pub enum PacketFlow { @@ -26,7 +26,8 @@ pub struct GameConnection { /// The buffered writer pub stream: TcpStream, pub compression_threshold: Option<u32>, - pub cipher: Option<Aes128Cfb>, + pub enc_cipher: Option<Aes128CfbEnc>, + pub dec_cipher: Option<Aes128CfbDec>, } pub struct StatusConnection { @@ -40,7 +41,8 @@ pub struct LoginConnection { /// The buffered writer pub stream: TcpStream, pub compression_threshold: Option<u32>, - pub cipher: Option<Aes128Cfb>, + pub enc_cipher: Option<Aes128CfbEnc>, + pub dec_cipher: Option<Aes128CfbDec>, } impl HandshakeConnection { @@ -68,7 +70,8 @@ impl HandshakeConnection { flow: self.flow, stream: self.stream, compression_threshold: None, - cipher: None, + enc_cipher: None, + dec_cipher: None, } } @@ -95,7 +98,7 @@ impl GameConnection { &self.flow, &mut self.stream, self.compression_threshold, - &mut self.cipher, + &mut self.dec_cipher, ) .await } @@ -106,7 +109,7 @@ impl GameConnection { packet, &mut self.stream, self.compression_threshold, - &mut self.cipher, + &mut self.enc_cipher, ) .await; } @@ -129,7 +132,7 @@ impl LoginConnection { &self.flow, &mut self.stream, self.compression_threshold, - &mut self.cipher, + &mut self.dec_cipher, ) .await } @@ -140,7 +143,7 @@ impl LoginConnection { packet, &mut self.stream, self.compression_threshold, - &mut self.cipher, + &mut self.enc_cipher, ) .await; } @@ -156,8 +159,9 @@ impl LoginConnection { pub fn set_encryption_key(&mut self, key: [u8; 16]) { // minecraft has a cipher decoder and encoder, i don't think it matters though? - let cipher = azalea_auth::encryption::create_cipher(&key); - self.cipher = Some(cipher); + let (enc_cipher, dec_cipher) = azalea_auth::encryption::create_cipher(&key); + self.enc_cipher = Some(enc_cipher); + self.dec_cipher = Some(dec_cipher); } pub fn game(self) -> GameConnection { @@ -165,7 +169,8 @@ impl LoginConnection { flow: self.flow, stream: self.stream, compression_threshold: self.compression_threshold, - cipher: self.cipher, + enc_cipher: self.enc_cipher, + dec_cipher: self.dec_cipher, } } } diff --git a/azalea-protocol/src/read.rs b/azalea-protocol/src/read.rs index 1e308cfb..88fe95cf 100755 --- a/azalea-protocol/src/read.rs +++ b/azalea-protocol/src/read.rs @@ -2,7 +2,7 @@ use std::{cell::Cell, pin::Pin}; use crate::{connect::PacketFlow, mc_buf::Readable, packets::ProtocolPacket}; use async_compression::tokio::bufread::ZlibDecoder; -use azalea_auth::encryption::Aes128Cfb; +use azalea_auth::encryption::Aes128CfbDec; use tokio::io::{AsyncRead, AsyncReadExt}; async fn frame_splitter<R: ?Sized>(mut stream: &mut R) -> Result<Vec<u8>, String> @@ -97,7 +97,7 @@ struct EncryptedStream<'a, R> where R: AsyncRead + std::marker::Unpin + std::marker::Send, { - cipher: Cell<&'a mut Option<Aes128Cfb>>, + cipher: Cell<&'a mut Option<Aes128CfbDec>>, stream: &'a mut Pin<&'a mut R>, } @@ -133,7 +133,7 @@ pub async fn read_packet<'a, P: ProtocolPacket, R>( flow: &PacketFlow, stream: &'a mut R, compression_threshold: Option<u32>, - cipher: &mut Option<Aes128Cfb>, + cipher: &mut Option<Aes128CfbDec>, ) -> Result<P, String> where R: AsyncRead + std::marker::Unpin + std::marker::Send + std::marker::Sync, diff --git a/azalea-protocol/src/write.rs b/azalea-protocol/src/write.rs index e72a74b1..e39ce18e 100755 --- a/azalea-protocol/src/write.rs +++ b/azalea-protocol/src/write.rs @@ -1,8 +1,9 @@ use crate::{mc_buf::Writable, packets::ProtocolPacket, read::MAXIMUM_UNCOMPRESSED_LENGTH}; use async_compression::tokio::bufread::ZlibEncoder; -use azalea_auth::encryption::Aes128Cfb; +use azalea_auth::encryption::Aes128CfbEnc; +use std::fmt::Debug; use tokio::{ - io::{AsyncReadExt, AsyncWriteExt}, + io::{AsyncReadExt, AsyncWrite, AsyncWriteExt}, net::TcpStream, }; @@ -51,13 +52,14 @@ async fn compression_encoder(data: &[u8], compression_threshold: u32) -> Result< } } -pub async fn write_packet<P>( +pub async fn write_packet<P, W>( packet: P, - stream: &mut TcpStream, + stream: &mut W, compression_threshold: Option<u32>, - cipher: &mut Option<Aes128Cfb>, + cipher: &mut Option<Aes128CfbEnc>, ) where - P: ProtocolPacket + std::fmt::Debug, + P: ProtocolPacket + Debug, + W: AsyncWrite + Unpin + Send, { let mut buf = packet_encoder(&packet).unwrap(); if let Some(threshold) = compression_threshold { diff --git a/bot/src/main.rs b/bot/src/main.rs index 8ae4ba1e..84867d78 100644 --- a/bot/src/main.rs +++ b/bot/src/main.rs @@ -3,7 +3,7 @@ async fn main() { println!("Hello, world!"); // let address = "95.111.249.143:10000"; - let address = "localhost:53193"; + let address = "localhost:50332"; // let response = azalea_client::ping::ping_server(&address.try_into().unwrap()) // .await // .unwrap(); |
