More Bedrock work

This commit is contained in:
Alexander Medvedev
2025-06-30 23:15:09 +02:00
parent 2d30f7af23
commit 637aada913
23 changed files with 646 additions and 59 deletions

View File

@@ -0,0 +1,62 @@
use pumpkin_macros::packet;
use crate::{ClientPacket, codec::u24::U24, ser::NetworkWriteExt};
#[packet(0xC0)]
pub struct Ack {
sequences: Vec<u32>,
}
impl Ack {
pub fn new(sequences: Vec<u32>) -> Self {
Self { sequences }
}
}
impl Ack {
fn write_range(
start: u32,
end: u32,
mut write: impl std::io::Write,
) -> Result<(), crate::ser::WritingError> {
if start == end {
write.write_u8_be(1)?;
U24::encode(&U24(start), &mut write)?;
} else {
write.write_u8_be(0)?;
U24::encode(&U24(start), &mut write)?;
U24::encode(&U24(end), &mut write)?;
}
Ok(())
}
}
impl ClientPacket for Ack {
fn write_packet_data(
&self,
mut write: impl std::io::Write,
) -> Result<(), crate::ser::WritingError> {
let mut buffer = Vec::new();
let mut count = 0;
let mut start = self.sequences[0];
let mut end = start;
for seq in self.sequences.clone() {
if seq == end + 1 {
end = seq
} else {
Self::write_range(start, end, &mut buffer)?;
count += 1;
start = seq;
end = seq;
}
}
Self::write_range(start, end, &mut buffer)?;
count += 1;
write.write_u16_be(count)?;
write.write_slice(&buffer)?;
Ok(())
}
}

View File

@@ -1,3 +1 @@
pub mod connection;
pub mod open_connection;
pub mod unconnected_pong;
pub mod raknet;

View File

@@ -0,0 +1,34 @@
use crate::ser::network_serialize_no_prefix;
use pumpkin_macros::packet;
use serde::Serialize;
use crate::codec::socket_address::SocketAddress;
#[derive(Serialize)]
#[packet(0x10)]
pub struct CConnectionRequestAccepted {
client_address: SocketAddress,
system_index: u16,
#[serde(serialize_with = "network_serialize_no_prefix")]
system_addresses: Vec<SocketAddress>,
requested_timestamp: u64,
timestamp: u64,
}
impl CConnectionRequestAccepted {
pub fn new(
client_address: SocketAddress,
system_index: u16,
system_addresses: Vec<SocketAddress>,
requested_timestamp: u64,
timestamp: u64,
) -> Self {
Self {
client_address,
system_index,
system_addresses,
requested_timestamp,
timestamp,
}
}
}

View File

@@ -0,0 +1,3 @@
pub mod connection;
pub mod open_connection;
pub mod unconnected_pong;

View File

@@ -28,6 +28,7 @@ impl COpenConnectionReply1 {
#[derive(Serialize)]
#[packet(0x08)]
pub struct COpenConnectionReply2 {
magic: [u8; 16],
server_guid: u64,
client_address: SocketAddress,
mtu: u16,
@@ -37,6 +38,7 @@ pub struct COpenConnectionReply2 {
impl COpenConnectionReply2 {
pub fn new(server_guid: u64, client_address: SocketAddress, mtu: u16, security: bool) -> Self {
Self {
magic: RAKNET_MAGIC,
server_guid,
client_address,
mtu,

View File

@@ -0,0 +1,131 @@
use std::io::Write;
use bytes::Bytes;
use pumpkin_macros::packet;
use crate::bedrock::{RAKNET_SPLIT, RakReliability};
use crate::codec::u24::U24;
use crate::ser::{NetworkReadExt, NetworkWriteExt, ReadingError, WritingError};
use crate::{ClientPacket, ServerPacket};
#[packet[0x80]]
pub struct FrameSet {
pub sequence: U24,
pub frames: Vec<Frame>,
}
impl ServerPacket for FrameSet {
fn read(mut read: impl std::io::Read) -> Result<Self, ReadingError> {
Ok(Self {
sequence: read.get_u24()?,
frames: Frame::read(read)?,
})
}
}
impl ClientPacket for FrameSet {
fn write_packet_data(&self, mut write: impl Write) -> Result<(), WritingError> {
write.write_u24_be(self.sequence)?;
for frame in &self.frames {
frame.write(&mut write)?;
}
Ok(())
}
}
#[derive(Default)]
pub struct Frame {
pub reliability: RakReliability,
pub payload: Bytes,
pub reliable_index: u32,
pub sequence_index: u32,
pub order_index: u32,
pub order_channel: u8,
pub split_size: u32,
pub split_id: u16,
pub split_index: u32,
}
impl Frame {
pub fn read(mut read: impl std::io::Read) -> Result<Vec<Self>, crate::ser::ReadingError> {
let mut frames = Vec::new();
while let Ok(header) = read.get_u8_be() {
let reliability_id = (header & 0xE0) >> 5;
let reliability = match RakReliability::from_id(reliability_id) {
Some(reliability) => reliability,
None => {
return Err(ReadingError::Message(format!(
"Invalid RakReliability {reliability_id}"
)));
}
};
let split = (header & RAKNET_SPLIT) != 0;
let length = (read.get_u16_be()? as f32 / 8.0).ceil();
let reliable_index = if reliability.is_reliable() {
read.get_u24()?.0
} else {
0
};
let sequence_index = if reliability.is_sequenced() {
read.get_u24()?.0
} else {
0
};
let (order_index, order_channel) = if reliability.is_ordered() {
(read.get_u24()?.0, read.get_u8_be()?)
} else {
(0, 0)
};
let (split_size, split_id, split_index) = if split {
(read.get_u32_be()?, read.get_u16_be()?, read.get_u32_be()?)
} else {
(0, 0, 0)
};
let payload = read.read_boxed_slice(length as usize)?;
frames.push(Self {
reliability,
payload: payload.into(),
reliable_index,
sequence_index,
order_index,
order_channel,
split_size,
split_id,
split_index,
});
}
Ok(frames)
}
fn write(&self, mut write: impl Write) -> Result<(), WritingError> {
let is_split = self.split_size > 0;
write.write_u8_be(
(self.reliability.to_id() >> 5) & if is_split { RAKNET_SPLIT } else { 0 },
)?;
write.write_u16_be((self.payload.len() >> 3) as u16)?;
if self.reliability.is_reliable() {
write.write_u24_be(U24(self.reliable_index))?;
}
if self.reliability.is_sequenced() {
write.write_u24_be(U24(self.sequence_index))?;
}
if self.reliability.is_ordered() {
write.write_u24_be(U24(self.order_index))?;
write.write_u8_be(self.order_channel)?;
}
if is_split {
write.write_u32_be(self.split_size)?;
write.write_u16_be(self.split_id)?;
write.write_u32_be(self.split_index)?;
}
write.write_slice(&self.payload).unwrap();
Ok(())
}
}

View File

@@ -1,4 +1,6 @@
pub mod ack;
pub mod client;
pub mod frame_set;
pub mod packet_decoder;
pub mod packet_encoder;
pub mod server;
@@ -6,3 +8,85 @@ pub mod server;
pub const RAKNET_MAGIC: [u8; 16] = [
0x00, 0xff, 0xff, 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0x12, 0x34, 0x56, 0x78,
];
pub const RAKNET_VALID: u8 = 0x80;
pub const RAKNET_ACK: u8 = 0xC0;
pub const RAKNET_NACK: u8 = 0xA0;
pub const RAKNET_SPLIT: u8 = 0x10;
#[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
pub enum RakReliability {
Unreliable,
UnreliableSequenced,
Reliable,
#[default]
ReliableOrdered,
ReliableSequenced,
UnreliableWithAckReceipt,
ReliableWithAckReceipt,
ReliableOrderedWithAckReceipt,
}
impl RakReliability {
pub fn is_reliable(&self) -> bool {
matches!(
self,
RakReliability::Reliable
| RakReliability::ReliableOrdered
| RakReliability::ReliableSequenced
| RakReliability::ReliableWithAckReceipt
| RakReliability::ReliableOrderedWithAckReceipt
)
}
pub fn is_sequenced(&self) -> bool {
matches!(
self,
RakReliability::ReliableSequenced | RakReliability::UnreliableSequenced
)
}
pub fn is_ordered(&self) -> bool {
matches!(
self,
RakReliability::UnreliableSequenced
| RakReliability::ReliableOrdered
| RakReliability::ReliableSequenced
| RakReliability::ReliableOrderedWithAckReceipt
)
}
pub fn is_order_exclusive(&self) -> bool {
matches!(
self,
RakReliability::ReliableOrdered | RakReliability::ReliableOrderedWithAckReceipt
)
}
pub fn from_id(id: u8) -> Option<Self> {
match id {
0 => Some(RakReliability::Unreliable),
1 => Some(RakReliability::UnreliableSequenced),
2 => Some(RakReliability::Reliable),
3 => Some(RakReliability::ReliableOrdered),
4 => Some(RakReliability::ReliableSequenced),
5 => Some(RakReliability::UnreliableWithAckReceipt),
6 => Some(RakReliability::ReliableWithAckReceipt),
7 => Some(RakReliability::ReliableOrderedWithAckReceipt),
_ => None,
}
}
pub fn to_id(&self) -> u8 {
match self {
RakReliability::Unreliable => 0,
RakReliability::UnreliableSequenced => 1,
RakReliability::Reliable => 2,
RakReliability::ReliableOrdered => 3,
RakReliability::ReliableSequenced => 4,
RakReliability::UnreliableWithAckReceipt => 5,
RakReliability::ReliableWithAckReceipt => 6,
RakReliability::ReliableOrderedWithAckReceipt => 7,
}
}
}

View File

@@ -1,10 +1,10 @@
use std::io::Cursor;
use async_compression::tokio::bufread::ZlibDecoder;
use bytes::Buf;
use bytes::Bytes;
use tokio::io::{AsyncRead, AsyncReadExt, BufReader};
use crate::{Aes128Cfb8Dec, CompressionThreshold, PacketDecodeError, RawPacket, StreamDecryptor};
use crate::{Aes128Cfb8Dec, CompressionThreshold, PacketDecodeError, StreamDecryptor};
// decrypt -> decompress -> raw
pub enum DecompressionReader<R: AsyncRead + Unpin> {
@@ -97,26 +97,16 @@ impl UDPNetworkDecoder {
// take_mut::take(&mut self.reader, |decoder| decoder.upgrade(cipher));
}
pub async fn get_raw_packet(
pub async fn get_packet_payload(
&mut self,
mut reader: Cursor<Vec<u8>>,
) -> Result<RawPacket, PacketDecodeError> {
// TODO: Serde is sync so we need to write to a buffer here :(
// Is there a way to deserialize in an asynchronous manner?
let packet_id = reader
.try_get_u8()
.map_err(|_| PacketDecodeError::DecodeID)?;
) -> Result<Bytes, PacketDecodeError> {
let mut payload = Vec::new();
reader
.read_to_end(&mut payload)
.await
.map_err(|err| PacketDecodeError::FailedDecompression(err.to_string()))?;
Ok(RawPacket {
id: packet_id as i32,
payload: payload.into(),
})
Ok(payload.into())
}
}

View File

@@ -1,10 +0,0 @@
use pumpkin_macros::packet;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
#[packet(0x09)]
pub struct SConnectionRequest {
pub client_guid: u64,
pub time: u64,
pub security: bool,
}

View File

@@ -1,3 +1 @@
pub mod connection;
pub mod open_connection;
pub mod unconnected_ping;
pub mod raknet;

View File

@@ -0,0 +1,25 @@
use pumpkin_macros::packet;
use serde::{Deserialize, Serialize};
use crate::codec::socket_address::SocketAddress;
#[derive(Serialize, Deserialize)]
#[packet(0x09)]
pub struct SConnectionRequest {
pub client_guid: u64,
pub time: u64,
pub security: bool,
}
#[derive(Serialize, Deserialize)]
#[packet(0x13)]
pub struct SNewIncomingConnection {
pub server_address: SocketAddress,
pub internal_address: SocketAddress,
pub ping_time: u64,
pub pong_time: u64,
}
#[derive(Serialize, Deserialize)]
#[packet(0x15)]
pub struct SDisconnect;

View File

@@ -0,0 +1,3 @@
pub mod connection;
pub mod open_connection;
pub mod unconnected_ping;

View File

@@ -2,5 +2,6 @@ pub mod ascii_string;
pub mod bit_set;
pub mod item_stack_seralizer;
pub mod socket_address;
pub mod u24;
pub mod var_int;
pub mod var_long;

View File

@@ -0,0 +1,64 @@
use std::io::{Read, Write};
use crate::ser::{NetworkReadExt, NetworkWriteExt, ReadingError, WritingError};
use serde::{
Deserialize,
de::{self, SeqAccess},
};
#[derive(Clone, Copy)]
pub struct U24(pub u32);
impl U24 {
pub fn decode(read: &mut impl Read) -> Result<Self, ReadingError> {
let a = read.get_u8_le()?;
let b = read.get_u8_le()?;
let c = read.get_u8_le()?;
Ok(U24(u32::from_le_bytes([a, b, c, 0])))
}
pub fn encode(&self, write: &mut impl Write) -> Result<(), WritingError> {
let data = self.0 & 0xFFFFFF; // Get the internal u32 value
write.write_u8_be((data & 0xFF) as u8)?;
write.write_u8_be(((data >> 8) & 0xFF) as u8)?;
write.write_u8_be(((data >> 16) & 0xFF) as u8)?;
Ok(())
}
}
impl<'de> Deserialize<'de> for U24 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = U24;
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
formatter.write_str("a valid u24")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut data: u32 = 0;
// Read the first byte (LSB)
data |= seq.next_element::<u8>()?.unwrap() as u32;
// Read the second byte and shift it by 8 bits
data |= (seq.next_element::<u8>()?.unwrap() as u32) << 8;
// Read the third next_element and shift it by 16 bits
data |= (seq.next_element::<u8>()?.unwrap() as u32) << 16;
// Mask to ensure only the lower 24 bits are kept
Ok(U24(data & 0xFFFFFF))
}
}
deserializer.deserialize_seq(Visitor)
}
}

View File

@@ -3,7 +3,7 @@ use std::io::{Read, Write};
use crate::{
FixedBitSet,
codec::{bit_set::BitSet, var_int::VarInt, var_long::VarLong},
codec::{bit_set::BitSet, u24::U24, var_int::VarInt, var_long::VarLong},
};
pub mod deserializer;
@@ -48,6 +48,8 @@ pub enum WritingError {
pub trait NetworkReadExt {
fn get_i8_be(&mut self) -> Result<i8, ReadingError>;
fn get_u8_be(&mut self) -> Result<u8, ReadingError>;
fn get_u8_le(&mut self) -> Result<u8, ReadingError>;
fn get_i16_be(&mut self) -> Result<i16, ReadingError>;
fn get_u16_be(&mut self) -> Result<u16, ReadingError>;
fn get_i32_be(&mut self) -> Result<i32, ReadingError>;
@@ -63,6 +65,7 @@ pub trait NetworkReadExt {
fn read_remaining_to_boxed_slice(&mut self, bound: usize) -> Result<Box<[u8]>, ReadingError>;
fn get_bool(&mut self) -> Result<bool, ReadingError>;
fn get_u24(&mut self) -> Result<U24, ReadingError>;
fn get_var_int(&mut self) -> Result<VarInt, ReadingError>;
fn get_var_long(&mut self) -> Result<VarLong, ReadingError>;
fn get_string_bounded(&mut self, bound: usize) -> Result<String, ReadingError>;
@@ -100,6 +103,14 @@ impl<R: Read> NetworkReadExt for R {
Ok(u8::from_be_bytes(buf))
}
fn get_u8_le(&mut self) -> Result<u8, ReadingError> {
let mut buf = [0u8];
self.read_exact(&mut buf)
.map_err(|err| ReadingError::Incomplete(err.to_string()))?;
Ok(u8::from_le_bytes(buf))
}
fn get_i16_be(&mut self) -> Result<i16, ReadingError> {
let mut buf = [0u8; 2];
self.read_exact(&mut buf)
@@ -116,6 +127,10 @@ impl<R: Read> NetworkReadExt for R {
Ok(u16::from_be_bytes(buf))
}
fn get_u24(&mut self) -> Result<U24, ReadingError> {
U24::decode(self)
}
fn get_i32_be(&mut self) -> Result<i32, ReadingError> {
let mut buf = [0u8; 4];
self.read_exact(&mut buf)
@@ -289,6 +304,7 @@ pub trait NetworkWriteExt {
fn write_u8_be(&mut self, data: u8) -> Result<(), WritingError>;
fn write_i16_be(&mut self, data: i16) -> Result<(), WritingError>;
fn write_u16_be(&mut self, data: u16) -> Result<(), WritingError>;
fn write_u24_be(&mut self, data: U24) -> Result<(), WritingError>;
fn write_i32_be(&mut self, data: i32) -> Result<(), WritingError>;
fn write_u32_be(&mut self, data: u32) -> Result<(), WritingError>;
fn write_i64_be(&mut self, data: i64) -> Result<(), WritingError>;
@@ -371,6 +387,10 @@ impl<W: Write> NetworkWriteExt for W {
.map_err(WritingError::IoError)
}
fn write_u24_be(&mut self, data: U24) -> Result<(), WritingError> {
data.encode(self)
}
fn write_i32_be(&mut self, data: i32) -> Result<(), WritingError> {
self.write_all(&data.to_be_bytes())
.map_err(WritingError::IoError)

View File

@@ -0,0 +1,34 @@
use std::{net::SocketAddr, time::UNIX_EPOCH};
use pumpkin_protocol::{
bedrock::{
RakReliability, client::raknet::connection::CConnectionRequestAccepted,
server::raknet::connection::SConnectionRequest,
},
codec::socket_address::SocketAddress,
};
use crate::net::{Client, bedrock::BedrockClientPlatform};
impl Client {
pub async fn handle_connection_request(
&self,
bedrock: &BedrockClientPlatform,
packet: SConnectionRequest,
) {
dbg!("send connection accepted");
bedrock
.send_framed_packet(
self,
&CConnectionRequestAccepted::new(
SocketAddress(*self.address.lock().await),
0,
vec![],
packet.time,
UNIX_EPOCH.elapsed().unwrap().as_millis() as u64,
),
RakReliability::Unreliable,
)
.await;
}
}

View File

@@ -1,25 +1,34 @@
use std::{
io::{Cursor, Write},
sync::Arc,
sync::{
Arc,
atomic::{AtomicBool, AtomicU32, Ordering},
},
};
use bytes::Bytes;
use pumpkin_protocol::{
ClientPacket, PacketDecodeError, PacketEncodeError, RawPacket, ServerPacket,
ClientPacket, PacketDecodeError, PacketEncodeError, ServerPacket,
bedrock::{
RAKNET_ACK, RAKNET_NACK, RAKNET_VALID, RakReliability,
ack::Ack,
frame_set::{Frame, FrameSet},
packet_decoder::UDPNetworkDecoder,
packet_encoder::UDPNetworkEncoder,
server::{
server::raknet::{
connection::{SConnectionRequest, SDisconnect},
open_connection::{SOpenConnectionRequest1, SOpenConnectionRequest2},
unconnected_ping::SUnconnectedPing,
},
},
codec::u24::U24,
packet::Packet,
ser::{NetworkWriteExt, ReadingError, WritingError},
ser::{NetworkReadExt, NetworkWriteExt, ReadingError, WritingError},
};
use std::net::SocketAddr;
use tokio::{net::UdpSocket, sync::Mutex};
pub mod connection;
pub mod open_connection;
pub mod unconnected;
@@ -33,6 +42,10 @@ pub struct BedrockClientPlatform {
network_writer: Arc<Mutex<UDPNetworkEncoder>>,
/// The packet decoder for incoming packets.
network_reader: Mutex<UDPNetworkDecoder>,
use_frame_sets: AtomicBool,
output_sequence: AtomicU32,
output_reliable_index: AtomicU32,
}
impl BedrockClientPlatform {
@@ -43,19 +56,18 @@ impl BedrockClientPlatform {
addr,
network_writer: Arc::new(Mutex::new(UDPNetworkEncoder::new())),
network_reader: Mutex::new(UDPNetworkDecoder::new()),
use_frame_sets: AtomicBool::new(false),
output_sequence: AtomicU32::new(0),
output_reliable_index: AtomicU32::new(0),
}
}
pub async fn process_packet(&self, client: &Client, server: &Server, packet: Cursor<Vec<u8>>) {
let packet = self.get_packet(client, packet).await;
let packet = self.get_packet_payload(client, packet).await;
if let Some(packet) = packet {
if let Err(error) = Self::handle_packet(client, server, &packet).await {
if let Err(error) = self.handle_packet_payload(client, server, packet).await {
let _text = format!("Error while reading incoming packet {error}");
log::error!(
"Failed to read incoming packet with id {}: {}",
packet.id,
error
);
log::error!("Failed to read incoming packet with : {error}");
//self.kick(TextComponent::text(text)).await;
}
}
@@ -78,12 +90,34 @@ impl BedrockClientPlatform {
.await
}
pub async fn send_packet_now(&self, client: &Client, packet: Vec<u8>) {
pub async fn send_framed_packet<P: ClientPacket>(
&self,
client: &Client,
packet: &P,
reliability: RakReliability,
) {
let mut packet_buf = Vec::new();
let writer = &mut packet_buf;
Self::write_packet(packet, writer).unwrap();
let frame = Frame {
payload: packet_buf.into(),
reliability,
reliable_index: self.output_reliable_index.fetch_add(1, Ordering::Relaxed),
..Default::default()
};
// TODO: this is really bad, batch this
let frame_set = FrameSet {
sequence: U24(self.output_sequence.fetch_add(1, Ordering::Relaxed)),
frames: vec![frame],
};
let mut packet_buf = Vec::new();
Self::write_packet(&frame_set, &mut packet_buf).unwrap();
if let Err(err) = self
.network_writer
.lock()
.await
.write_packet(packet.into(), self.addr, &self.socket)
.write_packet(packet_buf.into(), self.addr, &self.socket)
.await
{
// It is expected that the packet will fail if we are closed
@@ -96,13 +130,124 @@ impl BedrockClientPlatform {
}
}
pub async fn handle_packet(
pub async fn send_packet_now(&self, client: &Client, packet: Vec<u8>) {
if !self.use_frame_sets.load(Ordering::Relaxed) {
// Sent the packet directly
if let Err(err) = self
.network_writer
.lock()
.await
.write_packet(packet.into(), self.addr, &self.socket)
.await
{
// It is expected that the packet will fail if we are closed
if !client.closed.load(std::sync::atomic::Ordering::Relaxed) {
log::warn!("Failed to send packet to client {}: {}", client.id, err);
// We now need to close the connection to the client since the stream is in an
// unknown state
client.close();
}
}
}
}
pub async fn handle_packet_payload(
&self,
client: &Client,
server: &Server,
packet: &RawPacket,
packet: Bytes,
) -> Result<(), ReadingError> {
let payload = &packet.payload[..];
match packet.id {
let mut payload = &packet[..];
let Ok(id) = payload.get_u8_be() else {
return Err(ReadingError::CleanEOF(String::new()));
};
let is_valid = id & RAKNET_VALID == RAKNET_VALID;
if !is_valid {
// Offline packets just have Packet ID + Payload
return Self::handle_offline_packet(client, server, i32::from(id), payload).await;
}
self.use_frame_sets.store(true, Ordering::Relaxed);
let header = id;
match header {
RAKNET_ACK => {
dbg!("received ack");
}
RAKNET_NACK => {
dbg!("received non ack");
}
0x80..0x8d => {
self.handle_frame_set(client, server, FrameSet::read(payload)?)
.await;
}
_ => {
log::warn!("Received unknown online packet {header}");
}
}
Ok(())
}
async fn handle_frame_set(&self, client: &Client, server: &Server, frame_set: FrameSet) {
// TODO: this is bad
client
.send_packet_now(&Ack::new(vec![frame_set.sequence.0]))
.await;
// TODO
for frame in frame_set.frames {
self.handle_frame(client, server, &frame).await.unwrap();
}
}
async fn handle_frame(
&self,
client: &Client,
server: &Server,
frame: &Frame,
) -> Result<(), ReadingError> {
if frame.split_size > 0 {
dbg!("oh no, frame is split, TODO");
}
dbg!(frame.reliability);
let mut payload = &frame.payload[..];
let id = payload.get_u8_be()?;
self.handle_packet(client, server, i32::from(id), payload)
.await
}
async fn handle_packet(
&self,
client: &Client,
_server: &Server,
packet_id: i32,
payload: &[u8],
) -> Result<(), ReadingError> {
match packet_id {
SConnectionRequest::PACKET_ID => {
client
.handle_connection_request(self, SConnectionRequest::read(payload)?)
.await;
}
SDisconnect::PACKET_ID => {
dbg!("Bedrock client disconnected");
client.close();
}
_ => {
log::warn!("Received Online online packet {packet_id}");
}
}
Ok(())
}
async fn handle_offline_packet(
client: &Client,
server: &Server,
packet_id: i32,
payload: &[u8],
) -> Result<(), ReadingError> {
match packet_id {
SUnconnectedPing::PACKET_ID => {
client
.handle_unconnected_ping(server, SUnconnectedPing::read(payload)?)
@@ -119,20 +264,24 @@ impl BedrockClientPlatform {
.await;
}
_ => {
log::error!("Failed to handle bedrock client packet id {}", packet.id);
log::error!("Failed to handle bedrock client packet id {packet_id}");
}
}
Ok(())
}
pub async fn get_packet(&self, client: &Client, packet: Cursor<Vec<u8>>) -> Option<RawPacket> {
pub async fn get_packet_payload(
&self,
client: &Client,
packet: Cursor<Vec<u8>>,
) -> Option<Bytes> {
let mut network_reader = self.network_reader.lock().await;
tokio::select! {
() = client.await_close_interrupt() => {
log::debug!("Canceling player packet processing");
None
},
packet_result = network_reader.get_raw_packet(packet) => {
packet_result = network_reader.get_packet_payload(packet) => {
match packet_result {
Ok(packet) => Some(packet),
Err(err) => {

View File

@@ -1,7 +1,7 @@
use pumpkin_protocol::{
bedrock::{
client::open_connection::{COpenConnectionReply1, COpenConnectionReply2},
server::open_connection::{SOpenConnectionRequest1, SOpenConnectionRequest2},
client::raknet::open_connection::{COpenConnectionReply1, COpenConnectionReply2},
server::raknet::open_connection::{SOpenConnectionRequest1, SOpenConnectionRequest2},
},
codec::socket_address::SocketAddress,
};

View File

@@ -1,8 +1,8 @@
use pumpkin_config::BASIC_CONFIG;
use pumpkin_protocol::{
bedrock::{
client::unconnected_pong::{CUnconnectedPong, ServerInfo},
server::unconnected_ping::SUnconnectedPing,
client::raknet::unconnected_pong::{CUnconnectedPong, ServerInfo},
server::raknet::unconnected_ping::SUnconnectedPing,
},
codec::ascii_string::AsciiString,
};
@@ -14,8 +14,8 @@ impl Client {
let motd_string = ServerInfo {
edition: "MCPE",
motd_line_1: &BASIC_CONFIG.motd,
protocol_version: 527,
version_name: "1.19.1",
protocol_version: 818,
version_name: "1.21.90",
player_count: 1,
max_player_count: BASIC_CONFIG.max_players,
server_unique_id: server.server_guid,