aboutsummaryrefslogtreecommitdiff
path: root/azalea-protocol/src
diff options
context:
space:
mode:
Diffstat (limited to 'azalea-protocol/src')
-rw-r--r--azalea-protocol/src/connect.rs63
1 files changed, 56 insertions, 7 deletions
diff --git a/azalea-protocol/src/connect.rs b/azalea-protocol/src/connect.rs
index d7b9bd1d..03c56471 100644
--- a/azalea-protocol/src/connect.rs
+++ b/azalea-protocol/src/connect.rs
@@ -2,32 +2,36 @@
use crate::packets::game::{ClientboundGamePacket, ServerboundGamePacket};
use crate::packets::handshake::{ClientboundHandshakePacket, ServerboundHandshakePacket};
+use crate::packets::login::clientbound_hello_packet::ClientboundHelloPacket;
use crate::packets::login::{ClientboundLoginPacket, ServerboundLoginPacket};
use crate::packets::status::{ClientboundStatusPacket, ServerboundStatusPacket};
use crate::packets::ProtocolPacket;
use crate::read::{read_packet, ReadPacketError};
use crate::write::write_packet;
use crate::ServerIpAddress;
+use azalea_auth::sessionserver::SessionServerError;
use azalea_crypto::{Aes128CfbDec, Aes128CfbEnc};
use bytes::BytesMut;
use std::fmt::Debug;
use std::marker::PhantomData;
use thiserror::Error;
+use tokio::io::AsyncWriteExt;
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
use tokio::net::TcpStream;
+use uuid::Uuid;
pub struct ReadConnection<R: ProtocolPacket> {
- pub read_stream: OwnedReadHalf,
+ read_stream: OwnedReadHalf,
buffer: BytesMut,
- pub compression_threshold: Option<u32>,
- pub dec_cipher: Option<Aes128CfbDec>,
+ compression_threshold: Option<u32>,
+ dec_cipher: Option<Aes128CfbDec>,
_reading: PhantomData<R>,
}
pub struct WriteConnection<W: ProtocolPacket> {
- pub write_stream: OwnedWriteHalf,
- pub compression_threshold: Option<u32>,
- pub enc_cipher: Option<Aes128CfbEnc>,
+ write_stream: OwnedWriteHalf,
+ compression_threshold: Option<u32>,
+ enc_cipher: Option<Aes128CfbEnc>,
_writing: PhantomData<W>,
}
@@ -64,6 +68,10 @@ where
)
.await
}
+
+ pub async fn shutdown(&mut self) -> std::io::Result<()> {
+ self.write_stream.shutdown().await
+ }
}
impl<R, W> Connection<R, W>
@@ -145,13 +153,54 @@ impl Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
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 (enc_cipher, dec_cipher) = azalea_crypto::create_cipher(&key);
- self.writer.enc_cipher = Some(enc_cipher);
self.reader.dec_cipher = Some(dec_cipher);
+ self.writer.enc_cipher = Some(enc_cipher);
}
pub fn game(self) -> Connection<ClientboundGamePacket, ServerboundGamePacket> {
Connection::from(self)
}
+
+ /// Authenticate with Minecraft's servers, which is required to join
+ /// online-mode servers. This must happen when you get a
+ /// `ClientboundLoginPacket::Hello` packet.
+ ///
+ /// ```no_run
+ /// let token = azalea_auth::auth(azalea_auth::AuthOpts {
+ /// ..Default::default()
+ /// })
+ /// .await;
+ /// let player_data = azalea_auth::get_profile(token).await;
+ ///
+ /// let mut connection = azalea::Connection::new(&server_address).await?;
+ ///
+ /// // transition to the login state, in a real program we would have done a handshake first
+ /// connection.login();
+ ///
+ /// match connection.read().await? {
+ /// ClientboundLoginPacket::Hello(p) => {
+ /// // tell Mojang we're joining the server
+ /// connection.authenticate(&token, player_data.uuid, p).await?;
+ /// }
+ /// _ => {}
+ /// }
+ /// ```
+ pub async fn authenticate(
+ &self,
+ access_token: &str,
+ uuid: &Uuid,
+ private_key: [u8; 16],
+ packet: ClientboundHelloPacket,
+ ) -> Result<(), SessionServerError> {
+ azalea_auth::sessionserver::join(
+ access_token,
+ &packet.public_key,
+ &private_key,
+ uuid,
+ &packet.server_id,
+ )
+ .await
+ }
}
// rust doesn't let us implement From because allegedly it conflicts with