add more packets

This commit is contained in:
Alexander Medvedev
2025-07-02 15:48:57 +02:00
parent f21f552680
commit 2e643cdeb1
14 changed files with 216 additions and 17 deletions

View File

@@ -0,0 +1,14 @@
use pumpkin_macros::packet;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[packet(0x03)]
pub struct CHandshake {
jwt_data: String,
}
impl CHandshake {
pub fn new(jwt_data: String) -> Self {
Self { jwt_data }
}
}

View File

@@ -1,2 +1,6 @@
pub mod handshake;
pub mod network_settings; pub mod network_settings;
pub mod play_status;
pub mod raknet; pub mod raknet;
pub mod resource_pack_stack;
pub mod resource_packs_info;

View File

@@ -2,7 +2,7 @@ use pumpkin_macros::packet;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[packet(0x8F)] #[packet(143)]
pub struct CNetworkSettings { pub struct CNetworkSettings {
compression_threshold: u16, compression_threshold: u16,
compression_method: u16, compression_method: u16,

View File

@@ -0,0 +1,46 @@
use pumpkin_macros::packet;
use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize)]
#[packet(0x02)]
pub struct CPlayStatus {
status: i32,
}
impl CPlayStatus {
pub fn new(status: PlayStatus) -> Self {
Self {
status: status.to_index(),
}
}
}
pub enum PlayStatus {
LoginSuccess,
OutdatedClient,
OutdatedServer,
PlayerSpawn,
InvalidTenant,
EditionMismatchEduToVanilla,
EditionMismatchVanillaToEdu,
ServerFullSubClient,
EditorMismatchEditorToVanilla,
EditorMismatchVanillaToEditor,
}
impl PlayStatus {
pub fn to_index(&self) -> i32 {
match self {
PlayStatus::LoginSuccess => 0,
PlayStatus::OutdatedClient => 1,
PlayStatus::OutdatedServer => 2,
PlayStatus::PlayerSpawn => 3,
PlayStatus::InvalidTenant => 4,
PlayStatus::EditionMismatchEduToVanilla => 5,
PlayStatus::EditionMismatchVanillaToEdu => 6,
PlayStatus::ServerFullSubClient => 7,
PlayStatus::EditorMismatchEditorToVanilla => 8,
PlayStatus::EditorMismatchVanillaToEditor => 9,
}
}
}

View File

@@ -3,6 +3,22 @@ use serde::{Deserialize, Serialize};
use crate::codec::socket_address::SocketAddress; use crate::codec::socket_address::SocketAddress;
#[derive(Serialize, Deserialize)]
#[packet(0x03)]
pub struct CConnectedPong {
ping_time: u64,
pong_time: u64,
}
impl CConnectedPong {
pub fn new(ping_time: u64, pong_time: u64) -> Self {
Self {
ping_time,
pong_time,
}
}
}
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[packet(0x10)] #[packet(0x10)]
pub struct CConnectionRequestAccepted { pub struct CConnectionRequestAccepted {

View File

@@ -0,0 +1,20 @@
use pumpkin_macros::packet;
use serde::{Deserialize, Serialize};
use crate::codec::var_uint::VarUInt;
#[derive(Serialize, Deserialize)]
#[packet(0x07)]
pub struct CResourcePackStackPacket {
resource_pack_required: bool,
addons_list_size: VarUInt,
}
impl CResourcePackStackPacket {
pub fn new(resource_pack_required: bool, addons_list_size: VarUInt) -> Self {
Self {
resource_pack_required,
addons_list_size,
}
}
}

View File

@@ -0,0 +1,21 @@
use pumpkin_macros::packet;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[packet(0x06)]
pub struct CResourcePacksInfo {
resource_pack_required: bool,
has_addon_packs: bool,
has_scripts: bool,
// TODO: Add more
}
impl CResourcePacksInfo {
pub fn new(resource_pack_required: bool, has_addon_packs: bool, has_scripts: bool) -> Self {
Self {
resource_pack_required,
has_addon_packs,
has_scripts,
}
}
}

View File

@@ -131,7 +131,6 @@ impl UDPNetworkDecoder {
})?; })?;
let packet_len = packet_len.0 as u64; let packet_len = packet_len.0 as u64;
dbg!(packet_len);
// This is the default MTU size // This is the default MTU size
if !(0..=1492).contains(&packet_len) { if !(0..=1492).contains(&packet_len) {

View File

@@ -0,0 +1,9 @@
use pumpkin_macros::packet;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[packet(0x01)]
pub struct SLogin {
pub protocol_version: i32,
pub connection_request: String,
}

View File

@@ -1,2 +1,3 @@
pub mod login;
pub mod raknet; pub mod raknet;
pub mod request_network_settings; pub mod request_network_settings;

View File

@@ -3,6 +3,13 @@ use serde::{Deserialize, Serialize};
use crate::codec::socket_address::SocketAddress; use crate::codec::socket_address::SocketAddress;
#[derive(Serialize, Deserialize)]
#[packet(0x00)]
pub struct SConnectedPing {
/// Time since start
pub time: u64,
}
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[packet(0x09)] #[packet(0x09)]
pub struct SConnectionRequest { pub struct SConnectionRequest {

View File

@@ -7,8 +7,8 @@ use pumpkin_protocol::{
ConnectionState, ConnectionState,
bedrock::{ bedrock::{
RakReliability, RakReliability,
client::raknet::connection::CConnectionRequestAccepted, client::raknet::connection::{CConnectedPong, CConnectionRequestAccepted},
server::raknet::connection::{SConnectionRequest, SNewIncomingConnection}, server::raknet::connection::{SConnectedPing, SConnectionRequest, SNewIncomingConnection},
}, },
codec::socket_address::SocketAddress, codec::socket_address::SocketAddress,
}; };
@@ -44,4 +44,21 @@ impl Client {
dbg!(packet.pong_time); dbg!(packet.pong_time);
self.connection_state.store(ConnectionState::Login); self.connection_state.store(ConnectionState::Login);
} }
pub async fn handle_connected_ping(
&self,
bedrock: &BedrockClientPlatform,
packet: SConnectedPing,
) {
bedrock
.send_framed_packet(
self,
&CConnectedPong::new(
packet.time,
UNIX_EPOCH.elapsed().unwrap().as_millis() as u64,
),
RakReliability::Unreliable,
)
.await;
}
} }

View File

@@ -1,6 +1,15 @@
use pumpkin_protocol::bedrock::{ use pumpkin_protocol::{
RakReliability, client::network_settings::CNetworkSettings, bedrock::{
server::request_network_settings::SRequestNetworkSettings, RakReliability,
client::{
network_settings::CNetworkSettings,
play_status::{CPlayStatus, PlayStatus},
resource_pack_stack::CResourcePackStackPacket,
resource_packs_info::CResourcePacksInfo,
},
server::{login::SLogin, request_network_settings::SRequestNetworkSettings},
},
codec::var_uint::VarUInt,
}; };
use crate::net::{Client, bedrock::BedrockClientPlatform}; use crate::net::{Client, bedrock::BedrockClientPlatform};
@@ -24,4 +33,37 @@ impl Client {
) )
.await; .await;
} }
pub async fn handle_login(&self, bedrock: &BedrockClientPlatform, _packet: SLogin) {
dbg!("received login");
// TODO: Enable encryption
// bedrock
// .send_game_packet(
// self,
// &CHandshake::new(packet.connection_request),
// RakReliability::Unreliable,
// )
// .await;
// TODO: Batch these
bedrock
.send_game_packet(
self,
&CPlayStatus::new(PlayStatus::LoginSuccess),
RakReliability::Unreliable,
)
.await;
bedrock
.send_game_packet(
self,
&CResourcePacksInfo::new(false, false, false),
RakReliability::Unreliable,
)
.await;
bedrock
.send_game_packet(
self,
&CResourcePackStackPacket::new(false, VarUInt(0)),
RakReliability::Unreliable,
)
.await;
}
} }

View File

@@ -17,8 +17,11 @@ use pumpkin_protocol::{
packet_decoder::UDPNetworkDecoder, packet_decoder::UDPNetworkDecoder,
packet_encoder::UDPNetworkEncoder, packet_encoder::UDPNetworkEncoder,
server::{ server::{
login::SLogin,
raknet::{ raknet::{
connection::{SConnectionRequest, SDisconnect, SNewIncomingConnection}, connection::{
SConnectedPing, SConnectionRequest, SDisconnect, SNewIncomingConnection,
},
open_connection::{SOpenConnectionRequest1, SOpenConnectionRequest2}, open_connection::{SOpenConnectionRequest1, SOpenConnectionRequest2},
unconnected_ping::SUnconnectedPing, unconnected_ping::SUnconnectedPing,
}, },
@@ -274,9 +277,7 @@ impl BedrockClientPlatform {
Ok(()) Ok(())
} }
fn handle_ack(_ack: &Ack) { fn handle_ack(_ack: &Ack) {}
dbg!("received ack");
}
async fn handle_frame_set(&self, client: &Client, server: &Server, frame_set: FrameSet) { async fn handle_frame_set(&self, client: &Client, server: &Server, frame_set: FrameSet) {
dbg!("set", frame_set.sequence.0); dbg!("set", frame_set.sequence.0);
@@ -297,7 +298,6 @@ impl BedrockClientPlatform {
mut frame: Frame, mut frame: Frame,
) -> Result<(), ReadingError> { ) -> Result<(), ReadingError> {
if frame.split_size > 0 { if frame.split_size > 0 {
dbg!("oh yes, frame is split, not TODO");
let fragment_index = frame.split_index as usize; let fragment_index = frame.split_index as usize;
let compound_id = frame.split_id; let compound_id = frame.split_id;
let mut compounds = self.compounds.lock().await; let mut compounds = self.compounds.lock().await;
@@ -336,8 +336,6 @@ impl BedrockClientPlatform {
frame.split_size = 0; frame.split_size = 0;
} }
dbg!(frame.reliability);
let mut payload = &frame.payload[..]; let mut payload = &frame.payload[..];
let id = payload.get_u8()?; let id = payload.get_u8()?;
self.handle_raknet_packet(client, server, i32::from(id), payload) self.handle_raknet_packet(client, server, i32::from(id), payload)
@@ -351,13 +349,15 @@ impl BedrockClientPlatform {
packet: RawPacket, packet: RawPacket,
) -> Result<(), ReadingError> { ) -> Result<(), ReadingError> {
let payload = &packet.payload[..]; let payload = &packet.payload[..];
dbg!("payload", payload);
match packet.id { match packet.id {
SRequestNetworkSettings::PACKET_ID => { SRequestNetworkSettings::PACKET_ID => {
client client
.handle_request_network_settings(self, SRequestNetworkSettings::read(payload)?) .handle_request_network_settings(self, SRequestNetworkSettings::read(payload)?)
.await; .await;
} }
SLogin::PACKET_ID => {
client.handle_login(self, SLogin::read(payload)?).await;
}
_ => { _ => {
log::warn!("Bedrock: Received Unknown Game packet: {}", packet.id); log::warn!("Bedrock: Received Unknown Game packet: {}", packet.id);
} }
@@ -381,14 +381,17 @@ impl BedrockClientPlatform {
SNewIncomingConnection::PACKET_ID => { SNewIncomingConnection::PACKET_ID => {
client.handle_new_incoming_connection(&SNewIncomingConnection::read(payload)?); client.handle_new_incoming_connection(&SNewIncomingConnection::read(payload)?);
} }
SConnectedPing::PACKET_ID => {
client
.handle_connected_ping(self, SConnectedPing::read(payload)?)
.await;
}
SDisconnect::PACKET_ID => { SDisconnect::PACKET_ID => {
dbg!("Bedrock client disconnected"); dbg!("Bedrock client disconnected");
client.close(); client.close();
} }
RAKNET_GAME_PACKET => { RAKNET_GAME_PACKET => {
dbg!("game packet");
dbg!(payload.len());
let game_packet = self let game_packet = self
.network_reader .network_reader
.lock() .lock()