mirror of
https://github.com/mat-1/azalea.git
synced 2025-08-02 14:26:04 +00:00
make Connection a single struct with generics
This isn't that good of a solution but I couldn't come up with a better one and this was pretty simple to implement
This commit is contained in:
parent
0f380f1a12
commit
0c2ce00bae
3 changed files with 70 additions and 94 deletions
|
@ -3,7 +3,7 @@ use azalea_auth::game_profile::GameProfile;
|
|||
use azalea_core::{ChunkPos, EntityPos, PositionDelta, PositionDeltaTrait, ResourceLocation};
|
||||
use azalea_entity::Entity;
|
||||
use azalea_protocol::{
|
||||
connect::{GameConnection, HandshakeConnection},
|
||||
connect::Connection,
|
||||
packets::{
|
||||
game::{
|
||||
clientbound_player_chat_packet::ClientboundPlayerChatPacket,
|
||||
|
@ -12,7 +12,7 @@ use azalea_protocol::{
|
|||
serverbound_custom_payload_packet::ServerboundCustomPayloadPacket,
|
||||
serverbound_keep_alive_packet::ServerboundKeepAlivePacket,
|
||||
serverbound_move_player_packet_pos_rot::ServerboundMovePlayerPacketPosRot,
|
||||
ClientboundGamePacket,
|
||||
ClientboundGamePacket, ServerboundGamePacket,
|
||||
},
|
||||
handshake::client_intention_packet::ClientIntentionPacket,
|
||||
login::{
|
||||
|
@ -61,7 +61,7 @@ pub enum ChatPacket {
|
|||
#[derive(Clone)]
|
||||
pub struct Client {
|
||||
game_profile: GameProfile,
|
||||
pub conn: Arc<tokio::sync::Mutex<GameConnection>>,
|
||||
pub conn: Arc<tokio::sync::Mutex<Connection<ClientboundGamePacket, ServerboundGamePacket>>>,
|
||||
pub player: Arc<Mutex<Player>>,
|
||||
pub dimension: Arc<Mutex<Option<Dimension>>>,
|
||||
// game_loop
|
||||
|
@ -81,7 +81,7 @@ impl Client {
|
|||
) -> Result<(Self, UnboundedReceiver<Event>), String> {
|
||||
let resolved_address = resolver::resolve_address(address).await?;
|
||||
|
||||
let mut conn = HandshakeConnection::new(&resolved_address).await?;
|
||||
let mut conn = Connection::new(&resolved_address).await?;
|
||||
|
||||
// handshake
|
||||
conn.write(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
///! Ping Minecraft servers.
|
||||
use azalea_protocol::{
|
||||
connect::HandshakeConnection,
|
||||
connect::Connection,
|
||||
packets::{
|
||||
handshake::client_intention_packet::ClientIntentionPacket,
|
||||
status::{
|
||||
|
@ -18,7 +18,7 @@ pub async fn ping_server(
|
|||
) -> Result<ClientboundStatusResponsePacket, String> {
|
||||
let resolved_address = resolver::resolve_address(address).await?;
|
||||
|
||||
let mut conn = HandshakeConnection::new(&resolved_address).await?;
|
||||
let mut conn = Connection::new(&resolved_address).await?;
|
||||
|
||||
// send the client intention packet and switch to the status state
|
||||
conn.write(
|
||||
|
|
|
@ -4,40 +4,58 @@ use crate::packets::game::{ClientboundGamePacket, ServerboundGamePacket};
|
|||
use crate::packets::handshake::{ClientboundHandshakePacket, ServerboundHandshakePacket};
|
||||
use crate::packets::login::{ClientboundLoginPacket, ServerboundLoginPacket};
|
||||
use crate::packets::status::{ClientboundStatusPacket, ServerboundStatusPacket};
|
||||
use crate::packets::ProtocolPacket;
|
||||
use crate::read::read_packet;
|
||||
use crate::write::write_packet;
|
||||
use crate::ServerIpAddress;
|
||||
use azalea_crypto::{Aes128CfbDec, Aes128CfbEnc};
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
use tokio::net::TcpStream;
|
||||
|
||||
pub struct HandshakeConnection {
|
||||
/// The buffered writer
|
||||
pub stream: TcpStream,
|
||||
}
|
||||
pub struct Handshake;
|
||||
pub struct Game;
|
||||
pub struct Status;
|
||||
pub struct Login;
|
||||
|
||||
pub struct GameConnection {
|
||||
pub struct Connection<R: ProtocolPacket, W: ProtocolPacket> {
|
||||
/// The buffered writer
|
||||
pub stream: TcpStream,
|
||||
pub compression_threshold: Option<u32>,
|
||||
pub enc_cipher: Option<Aes128CfbEnc>,
|
||||
pub dec_cipher: Option<Aes128CfbDec>,
|
||||
_reading: PhantomData<R>,
|
||||
_writing: PhantomData<W>,
|
||||
}
|
||||
|
||||
pub struct StatusConnection {
|
||||
/// The buffered writer
|
||||
pub stream: TcpStream,
|
||||
impl<R, W> Connection<R, W>
|
||||
where
|
||||
R: ProtocolPacket + Debug,
|
||||
W: ProtocolPacket + Debug,
|
||||
{
|
||||
pub async fn read(&mut self) -> Result<R, String> {
|
||||
read_packet::<R, _>(
|
||||
&mut self.stream,
|
||||
self.compression_threshold,
|
||||
&mut self.dec_cipher,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Write a packet to the server
|
||||
pub async fn write(&mut self, packet: W) {
|
||||
write_packet(
|
||||
packet,
|
||||
&mut self.stream,
|
||||
self.compression_threshold,
|
||||
&mut self.enc_cipher,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LoginConnection {
|
||||
/// The buffered writer
|
||||
pub stream: TcpStream,
|
||||
pub compression_threshold: Option<u32>,
|
||||
pub enc_cipher: Option<Aes128CfbEnc>,
|
||||
pub dec_cipher: Option<Aes128CfbDec>,
|
||||
}
|
||||
|
||||
impl HandshakeConnection {
|
||||
pub async fn new(address: &ServerIpAddress) -> Result<HandshakeConnection, String> {
|
||||
impl Connection<ClientboundHandshakePacket, ServerboundHandshakePacket> {
|
||||
pub async fn new(address: &ServerIpAddress) -> Result<Self, String> {
|
||||
let ip = address.ip;
|
||||
let port = address.port;
|
||||
|
||||
|
@ -50,88 +68,44 @@ impl HandshakeConnection {
|
|||
.set_nodelay(true)
|
||||
.expect("Error enabling tcp_nodelay");
|
||||
|
||||
Ok(HandshakeConnection { stream })
|
||||
}
|
||||
|
||||
pub fn login(self) -> LoginConnection {
|
||||
LoginConnection {
|
||||
stream: self.stream,
|
||||
Ok(Connection {
|
||||
stream,
|
||||
compression_threshold: None,
|
||||
enc_cipher: None,
|
||||
dec_cipher: None,
|
||||
}
|
||||
_reading: PhantomData,
|
||||
_writing: PhantomData,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn status(self) -> StatusConnection {
|
||||
StatusConnection {
|
||||
pub fn login(self) -> Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
|
||||
Connection {
|
||||
stream: self.stream,
|
||||
compression_threshold: self.compression_threshold,
|
||||
enc_cipher: self.enc_cipher,
|
||||
dec_cipher: self.dec_cipher,
|
||||
_reading: PhantomData,
|
||||
_writing: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn read(&mut self) -> Result<ClientboundHandshakePacket, String> {
|
||||
read_packet::<ClientboundHandshakePacket, _>(&mut self.stream, None, &mut None).await
|
||||
}
|
||||
|
||||
/// Write a packet to the server
|
||||
pub async fn write(&mut self, packet: ServerboundHandshakePacket) {
|
||||
write_packet(packet, &mut self.stream, None, &mut None).await;
|
||||
pub fn status(self) -> Connection<ClientboundStatusPacket, ServerboundStatusPacket> {
|
||||
Connection {
|
||||
stream: self.stream,
|
||||
compression_threshold: self.compression_threshold,
|
||||
enc_cipher: self.enc_cipher,
|
||||
dec_cipher: self.dec_cipher,
|
||||
_reading: PhantomData,
|
||||
_writing: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GameConnection {
|
||||
pub async fn read(&mut self) -> Result<ClientboundGamePacket, String> {
|
||||
read_packet::<ClientboundGamePacket, _>(
|
||||
&mut self.stream,
|
||||
self.compression_threshold,
|
||||
&mut self.dec_cipher,
|
||||
)
|
||||
.await
|
||||
}
|
||||
impl Connection<ClientboundGamePacket, ServerboundGamePacket> {}
|
||||
|
||||
/// Write a packet to the server
|
||||
pub async fn write(&mut self, packet: ServerboundGamePacket) {
|
||||
write_packet(
|
||||
packet,
|
||||
&mut self.stream,
|
||||
self.compression_threshold,
|
||||
&mut self.enc_cipher,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
impl StatusConnection {
|
||||
pub async fn read(&mut self) -> Result<ClientboundStatusPacket, String> {
|
||||
read_packet::<ClientboundStatusPacket, _>(&mut self.stream, None, &mut None).await
|
||||
}
|
||||
|
||||
/// Write a packet to the server
|
||||
pub async fn write(&mut self, packet: ServerboundStatusPacket) {
|
||||
write_packet(packet, &mut self.stream, None, &mut None).await;
|
||||
}
|
||||
}
|
||||
|
||||
impl LoginConnection {
|
||||
pub async fn read(&mut self) -> Result<ClientboundLoginPacket, String> {
|
||||
read_packet::<ClientboundLoginPacket, _>(
|
||||
&mut self.stream,
|
||||
self.compression_threshold,
|
||||
&mut self.dec_cipher,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Write a packet to the server
|
||||
pub async fn write(&mut self, packet: ServerboundLoginPacket) {
|
||||
write_packet(
|
||||
packet,
|
||||
&mut self.stream,
|
||||
self.compression_threshold,
|
||||
&mut self.enc_cipher,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
impl Connection<ClientboundStatusPacket, ServerboundStatusPacket> {}
|
||||
|
||||
impl Connection<ClientboundLoginPacket, ServerboundLoginPacket> {
|
||||
pub fn set_compression_threshold(&mut self, threshold: i32) {
|
||||
// if you pass a threshold of 0 or less, compression is disabled
|
||||
if threshold > 0 {
|
||||
|
@ -148,12 +122,14 @@ impl LoginConnection {
|
|||
self.dec_cipher = Some(dec_cipher);
|
||||
}
|
||||
|
||||
pub fn game(self) -> GameConnection {
|
||||
GameConnection {
|
||||
pub fn game(self) -> Connection<ClientboundGamePacket, ServerboundGamePacket> {
|
||||
Connection {
|
||||
stream: self.stream,
|
||||
compression_threshold: self.compression_threshold,
|
||||
enc_cipher: self.enc_cipher,
|
||||
dec_cipher: self.dec_cipher,
|
||||
_reading: PhantomData,
|
||||
_writing: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue