mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
try to implement game packet
This commit is contained in:
@@ -1 +1,2 @@
|
||||
pub mod network_settings;
|
||||
pub mod raknet;
|
||||
|
||||
30
pumpkin-protocol/src/bedrock/client/network_settings.rs
Normal file
30
pumpkin-protocol/src/bedrock/client/network_settings.rs
Normal file
@@ -0,0 +1,30 @@
|
||||
use pumpkin_macros::packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(0x8F)]
|
||||
pub struct CNetworkSettings {
|
||||
compression_threshold: u16,
|
||||
compression_method: u16,
|
||||
client_throttle_enabled: bool,
|
||||
client_throttle_threshold: i8,
|
||||
client_throttle_scalar: f32,
|
||||
}
|
||||
|
||||
impl CNetworkSettings {
|
||||
pub fn new(
|
||||
compression_threshold: u16,
|
||||
compression_method: u16,
|
||||
client_throttle_enabled: bool,
|
||||
client_throttle_threshold: i8,
|
||||
client_throttle_scalar: f32,
|
||||
) -> Self {
|
||||
Self {
|
||||
compression_threshold,
|
||||
compression_method,
|
||||
client_throttle_enabled,
|
||||
client_throttle_threshold,
|
||||
client_throttle_scalar,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
use pumpkin_macros::packet;
|
||||
use serde::Serialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::codec::socket_address::SocketAddress;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(0x10)]
|
||||
pub struct CConnectionRequestAccepted {
|
||||
client_address: SocketAddress,
|
||||
|
||||
@@ -14,6 +14,9 @@ pub const RAKNET_MAGIC: [u8; 16] = [
|
||||
pub const RAKNET_VALID: u8 = 0x80;
|
||||
pub const RAKNET_ACK: u8 = 0xC0;
|
||||
pub const RAKNET_NACK: u8 = 0xA0;
|
||||
|
||||
pub const RAKNET_GAME_PACKET: i32 = 0xfe;
|
||||
|
||||
pub const RAKNET_SPLIT: u8 = 0x10;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
|
||||
|
||||
@@ -4,7 +4,12 @@ use async_compression::tokio::bufread::ZlibDecoder;
|
||||
use bytes::Bytes;
|
||||
use tokio::io::{AsyncRead, AsyncReadExt, BufReader};
|
||||
|
||||
use crate::{Aes128Cfb8Dec, CompressionThreshold, PacketDecodeError, StreamDecryptor};
|
||||
use crate::{
|
||||
Aes128Cfb8Dec, CompressionThreshold, MAX_PACKET_SIZE, PacketDecodeError, RawPacket,
|
||||
StreamDecryptor,
|
||||
codec::var_int::VarInt,
|
||||
ser::{NetworkReadExt, ReadingError},
|
||||
};
|
||||
|
||||
// decrypt -> decompress -> raw
|
||||
pub enum DecompressionReader<R: AsyncRead + Unpin> {
|
||||
@@ -109,4 +114,58 @@ impl UDPNetworkDecoder {
|
||||
|
||||
Ok(payload.into())
|
||||
}
|
||||
|
||||
pub async fn get_game_packet(
|
||||
&mut self,
|
||||
mut reader: Cursor<Vec<u8>>,
|
||||
) -> Result<RawPacket, PacketDecodeError> {
|
||||
let compression = reader.get_u8_be()?;
|
||||
dbg!(compression);
|
||||
|
||||
// TODO: compression & encryption
|
||||
let packet_len = VarInt::decode_async(&mut reader)
|
||||
.await
|
||||
.map_err(|err| match err {
|
||||
ReadingError::CleanEOF(_) => PacketDecodeError::ConnectionClosed,
|
||||
err => PacketDecodeError::MalformedLength(err.to_string()),
|
||||
})?;
|
||||
|
||||
let packet_len = packet_len.0 as u64;
|
||||
dbg!(packet_len);
|
||||
|
||||
if !(0..=MAX_PACKET_SIZE).contains(&packet_len) {
|
||||
Err(PacketDecodeError::OutOfBounds)?
|
||||
}
|
||||
|
||||
let header = VarInt::decode_async(&mut reader).await?;
|
||||
|
||||
let header_value = header.0;
|
||||
|
||||
// Extract components from GamePacket Header (14 bits)
|
||||
// Gamepacket ID (10 bits)
|
||||
// SubClient Sender ID (2 bits)
|
||||
// SubClient Target ID (2 bits)
|
||||
|
||||
// The header is 14 bits. Ensure we only consider these bits.
|
||||
// A varint u32 could be larger, so we mask to the relevant bits.
|
||||
let fourteen_bit_header = header_value & 0x3FFF; // Mask to get the lower 14 bits (2^14 - 1)
|
||||
|
||||
// SubClient Target ID: Lowest 2 bits
|
||||
let _sub_client_target_id = (fourteen_bit_header & 0b11) as u8;
|
||||
|
||||
// SubClient Sender ID: Next 2 bits (bits 2 and 3)
|
||||
let _sub_client_sender_id = ((fourteen_bit_header >> 2) & 0b11) as u8;
|
||||
|
||||
// Gamepacket ID: Remaining 10 bits (bits 4 to 13)
|
||||
let gamepacket_id = ((fourteen_bit_header >> 4) & 0x3FF) as u16; // 0x3FF is 10 bits set to 1
|
||||
|
||||
let payload = reader
|
||||
.read_boxed_slice(packet_len as usize)
|
||||
.map_err(|err| PacketDecodeError::FailedDecompression(err.to_string()))?;
|
||||
|
||||
Ok(RawPacket {
|
||||
id: gamepacket_id as i32,
|
||||
payload: payload.into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::net::SocketAddr;
|
||||
use std::{io::Write, net::SocketAddr};
|
||||
|
||||
use bytes::Bytes;
|
||||
use thiserror::Error;
|
||||
@@ -6,6 +6,7 @@ use tokio::{io::AsyncWrite, net::UdpSocket};
|
||||
|
||||
use crate::{
|
||||
Aes128Cfb8Enc, CompressionLevel, CompressionThreshold, PacketEncodeError, StreamEncryptor,
|
||||
codec::var_int::VarInt, ser::NetworkWriteExt,
|
||||
};
|
||||
|
||||
// raw -> compress -> encrypt
|
||||
@@ -107,6 +108,57 @@ impl UDPNetworkEncoder {
|
||||
// take_mut::take(&mut self.writer, |encoder| encoder.upgrade(cipher));
|
||||
}
|
||||
|
||||
pub async fn write_game_packet(
|
||||
&mut self,
|
||||
packet_id: i32,
|
||||
sub_client_sender_id: i32,
|
||||
sub_client_target_id: i32,
|
||||
packet_payload: Bytes,
|
||||
mut writer: impl Write,
|
||||
) -> Result<(), PacketEncodeError> {
|
||||
// Game Packet ID
|
||||
writer.write_u8(0xfe).unwrap();
|
||||
|
||||
// TODO: compression & encryption
|
||||
|
||||
// Gamepacket ID (10 bits) << 4 (offset by 2 bits for target + 2 bits for sender)
|
||||
// SubClient Sender ID (2 bits) << 2 (offset by 2 bits for target)
|
||||
// SubClient Target ID (2 bits)
|
||||
let header_value: u32 = ((packet_id as u32) << 4)
|
||||
| ((sub_client_sender_id as u32) << 2)
|
||||
| (sub_client_target_id as u32);
|
||||
|
||||
// Ensure the combined header doesn't exceed 14 bits (just a sanity check, should be handled by above shifts)
|
||||
let fourteen_bit_header = header_value & 0x3FFF; // Mask to ensure it fits in 14 bits
|
||||
|
||||
// 2. Calculate total packet_len
|
||||
// This is where `VarInt::encoded_len` is crucial.
|
||||
// We need to know the byte length of the header's VarInt *before* we write the packet_len.
|
||||
let header_byte_len = VarInt(fourteen_bit_header as i32).written_size();
|
||||
|
||||
let packet_payload_len = packet_payload.len() as u32;
|
||||
// total_content_length is the length of the header VarInt bytes + payload bytes.
|
||||
let total_content_length = header_byte_len as u32 + packet_payload_len;
|
||||
|
||||
// 3. Write packet_len as VarInt
|
||||
// Note: Your `VarInt` struct takes `i32`, but lengths are typically `u32`.
|
||||
// Ensure consistency in your actual `VarInt` definition.
|
||||
// For this example, I'll cast `total_content_length` to `i32`.
|
||||
writer
|
||||
.write_var_int(&VarInt(total_content_length as i32))
|
||||
.unwrap();
|
||||
|
||||
// 4. Write the combined 14-bit header_value as VarInt
|
||||
writer
|
||||
.write_var_int(&VarInt(fourteen_bit_header as i32))
|
||||
.unwrap();
|
||||
|
||||
// 5. Write the Packet ID + payload
|
||||
writer.write_u8(packet_id as u8).unwrap();
|
||||
writer.write_all(&packet_payload).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn write_packet(
|
||||
&mut self,
|
||||
packet_data: Bytes,
|
||||
@@ -114,7 +166,6 @@ impl UDPNetworkEncoder {
|
||||
socket: &UdpSocket,
|
||||
) -> Result<(), PacketEncodeError> {
|
||||
socket.send_to(&packet_data, addr).await.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
pub mod raknet;
|
||||
pub mod request_network_settings;
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
use pumpkin_macros::packet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[packet(0xC1)]
|
||||
pub struct SRequestNetworkSettings {
|
||||
pub protocol_version: i32,
|
||||
}
|
||||
@@ -363,7 +363,6 @@ async fn move_piston(
|
||||
|
||||
let mut moved_blocks_map: HashMap<BlockPos, BlockState> = HashMap::new();
|
||||
let moved_blocks: Vec<BlockPos> = handler.moved_blocks;
|
||||
dbg!(&moved_blocks);
|
||||
|
||||
let mut moved_block_states: Vec<BlockState> = Vec::new();
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ use std::{
|
||||
};
|
||||
|
||||
use pumpkin_protocol::{
|
||||
ConnectionState,
|
||||
bedrock::{
|
||||
RakReliability, client::raknet::connection::CConnectionRequestAccepted,
|
||||
server::raknet::connection::SConnectionRequest,
|
||||
RakReliability,
|
||||
client::raknet::connection::CConnectionRequestAccepted,
|
||||
server::raknet::connection::{SConnectionRequest, SNewIncomingConnection},
|
||||
},
|
||||
codec::socket_address::SocketAddress,
|
||||
};
|
||||
@@ -37,4 +39,9 @@ impl Client {
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub fn handle_new_incoming_connection(&self, packet: &SNewIncomingConnection) {
|
||||
dbg!(packet.pong_time);
|
||||
self.connection_state.store(ConnectionState::Login);
|
||||
}
|
||||
}
|
||||
|
||||
27
pumpkin/src/net/bedrock/login.rs
Normal file
27
pumpkin/src/net/bedrock/login.rs
Normal file
@@ -0,0 +1,27 @@
|
||||
use pumpkin_protocol::bedrock::{
|
||||
RakReliability, client::network_settings::CNetworkSettings,
|
||||
server::request_network_settings::SRequestNetworkSettings,
|
||||
};
|
||||
|
||||
use crate::net::{Client, bedrock::BedrockClientPlatform};
|
||||
|
||||
impl Client {
|
||||
pub async fn handle_request_network_settings(
|
||||
&self,
|
||||
bedrock: &BedrockClientPlatform,
|
||||
packet: SRequestNetworkSettings,
|
||||
) {
|
||||
dbg!("requested network settings");
|
||||
self.protocol_version.store(
|
||||
packet.protocol_version,
|
||||
std::sync::atomic::Ordering::Relaxed,
|
||||
);
|
||||
bedrock
|
||||
.send_game_packet(
|
||||
self,
|
||||
&CNetworkSettings::new(0, 0xFF, false, 0, 0.0),
|
||||
RakReliability::Unreliable,
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
@@ -8,17 +8,20 @@ use std::{
|
||||
|
||||
use bytes::Bytes;
|
||||
use pumpkin_protocol::{
|
||||
ClientPacket, PacketDecodeError, PacketEncodeError, ServerPacket,
|
||||
ClientPacket, PacketDecodeError, PacketEncodeError, RawPacket, ServerPacket,
|
||||
bedrock::{
|
||||
RAKNET_ACK, RAKNET_NACK, RAKNET_VALID, RakReliability,
|
||||
RAKNET_ACK, RAKNET_GAME_PACKET, RAKNET_NACK, RAKNET_VALID, RakReliability,
|
||||
ack::Ack,
|
||||
frame_set::{Frame, FrameSet},
|
||||
packet_decoder::UDPNetworkDecoder,
|
||||
packet_encoder::UDPNetworkEncoder,
|
||||
server::raknet::{
|
||||
connection::{SConnectionRequest, SDisconnect},
|
||||
open_connection::{SOpenConnectionRequest1, SOpenConnectionRequest2},
|
||||
unconnected_ping::SUnconnectedPing,
|
||||
server::{
|
||||
raknet::{
|
||||
connection::{SConnectionRequest, SDisconnect, SNewIncomingConnection},
|
||||
open_connection::{SOpenConnectionRequest1, SOpenConnectionRequest2},
|
||||
unconnected_ping::SUnconnectedPing,
|
||||
},
|
||||
request_network_settings::SRequestNetworkSettings,
|
||||
},
|
||||
},
|
||||
codec::u24::U24,
|
||||
@@ -29,6 +32,7 @@ use std::net::SocketAddr;
|
||||
use tokio::{net::UdpSocket, sync::Mutex};
|
||||
|
||||
pub mod connection;
|
||||
pub mod login;
|
||||
pub mod open_connection;
|
||||
pub mod unconnected;
|
||||
|
||||
@@ -77,7 +81,7 @@ impl BedrockClientPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_packet<P: ClientPacket>(
|
||||
pub fn write_raw_packet<P: ClientPacket>(
|
||||
packet: &P,
|
||||
mut write: impl Write,
|
||||
) -> Result<(), WritingError> {
|
||||
@@ -85,6 +89,24 @@ impl BedrockClientPlatform {
|
||||
packet.write_packet_data(write)
|
||||
}
|
||||
|
||||
pub async fn write_game_packet<P: ClientPacket>(
|
||||
&self,
|
||||
packet: &P,
|
||||
write: impl Write,
|
||||
) -> Result<(), WritingError> {
|
||||
let mut packet_payload = Vec::new();
|
||||
packet.write_packet_data(&mut packet_payload)?;
|
||||
|
||||
// TODO
|
||||
self.network_writer
|
||||
.lock()
|
||||
.await
|
||||
.write_game_packet(P::PACKET_ID, 0, 0, packet_payload.into(), write)
|
||||
.await
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn write_packet_data(&self, packet_data: Bytes) -> Result<(), PacketEncodeError> {
|
||||
self.network_writer
|
||||
.lock()
|
||||
@@ -93,20 +115,49 @@ impl BedrockClientPlatform {
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn send_raknet_packet_now<P: ClientPacket>(&self, client: &Client, packet: &P) {
|
||||
let mut packet_buf = Vec::new();
|
||||
let writer = &mut packet_buf;
|
||||
Self::write_raw_packet(packet, writer).unwrap();
|
||||
self.send_packet_now(client, packet_buf).await;
|
||||
}
|
||||
|
||||
pub async fn send_game_packet<P: ClientPacket>(
|
||||
&self,
|
||||
client: &Client,
|
||||
packet: &P,
|
||||
reliability: RakReliability,
|
||||
) {
|
||||
let mut packet_buf = Vec::new();
|
||||
self.write_game_packet(packet, &mut packet_buf)
|
||||
.await
|
||||
.unwrap();
|
||||
self.send_framed_packet_data(client, packet_buf, reliability)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn send_framed_packet<P: ClientPacket>(
|
||||
&self,
|
||||
client: &Client,
|
||||
packet: &P,
|
||||
reliability: RakReliability,
|
||||
) {
|
||||
let mut packet_buf = Vec::new();
|
||||
Self::write_raw_packet(packet, &mut packet_buf).unwrap();
|
||||
self.send_framed_packet_data(client, packet_buf, reliability)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn send_framed_packet_data(
|
||||
&self,
|
||||
client: &Client,
|
||||
packet_buf: Vec<u8>,
|
||||
reliability: RakReliability,
|
||||
) {
|
||||
let mut frame_set = FrameSet {
|
||||
sequence: U24(self.output_sequence_number.fetch_add(1, Ordering::Relaxed)),
|
||||
frames: Vec::with_capacity(1),
|
||||
};
|
||||
// Todo! Calculate required capacity
|
||||
let mut packet_buf = Vec::new();
|
||||
Self::write_packet(packet, &mut packet_buf).unwrap();
|
||||
|
||||
let mut frame = Frame {
|
||||
payload: packet_buf.into(),
|
||||
reliability,
|
||||
@@ -186,7 +237,9 @@ impl BedrockClientPlatform {
|
||||
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;
|
||||
return self
|
||||
.handle_offline_packet(client, server, i32::from(id), payload)
|
||||
.await;
|
||||
}
|
||||
self.use_frame_sets.store(true, Ordering::Relaxed);
|
||||
let header = id;
|
||||
@@ -203,7 +256,7 @@ impl BedrockClientPlatform {
|
||||
.await;
|
||||
}
|
||||
_ => {
|
||||
log::warn!("Received unknown online packet {header}");
|
||||
log::warn!("Bedrock: Received unknown packet header {header}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@@ -238,14 +291,34 @@ impl BedrockClientPlatform {
|
||||
|
||||
let mut payload = &frame.payload[..];
|
||||
let id = payload.get_u8_be()?;
|
||||
self.handle_packet(client, server, i32::from(id), payload)
|
||||
self.handle_raknet_packet(client, server, i32::from(id), payload)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn handle_packet(
|
||||
async fn handle_game_packet(
|
||||
&self,
|
||||
client: &Client,
|
||||
_server: &Server,
|
||||
packet: RawPacket,
|
||||
) -> Result<(), ReadingError> {
|
||||
let payload = &packet.payload[..];
|
||||
match packet.id {
|
||||
SRequestNetworkSettings::PACKET_ID => {
|
||||
client
|
||||
.handle_request_network_settings(self, SRequestNetworkSettings::read(payload)?)
|
||||
.await;
|
||||
}
|
||||
_ => {
|
||||
log::warn!("Bedrock: Received Unknown Game packet: {}", packet.id);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_raknet_packet(
|
||||
&self,
|
||||
client: &Client,
|
||||
server: &Server,
|
||||
packet_id: i32,
|
||||
payload: &[u8],
|
||||
) -> Result<(), ReadingError> {
|
||||
@@ -255,18 +328,36 @@ impl BedrockClientPlatform {
|
||||
.handle_connection_request(self, SConnectionRequest::read(payload)?)
|
||||
.await;
|
||||
}
|
||||
SNewIncomingConnection::PACKET_ID => {
|
||||
client.handle_new_incoming_connection(&SNewIncomingConnection::read(payload)?);
|
||||
}
|
||||
SDisconnect::PACKET_ID => {
|
||||
dbg!("Bedrock client disconnected");
|
||||
client.close();
|
||||
}
|
||||
|
||||
RAKNET_GAME_PACKET => {
|
||||
dbg!("game packet");
|
||||
dbg!(payload.len());
|
||||
let game_packet = self
|
||||
.network_reader
|
||||
.lock()
|
||||
.await
|
||||
.get_game_packet(Cursor::new(payload.to_vec()))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
self.handle_game_packet(client, server, game_packet).await?;
|
||||
}
|
||||
_ => {
|
||||
log::warn!("Received Online online packet {packet_id}");
|
||||
log::warn!("Bedrock: Received Unknown RakNet Online packet: {packet_id}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_offline_packet(
|
||||
&self,
|
||||
client: &Client,
|
||||
server: &Server,
|
||||
packet_id: i32,
|
||||
@@ -275,21 +366,21 @@ impl BedrockClientPlatform {
|
||||
match packet_id {
|
||||
SUnconnectedPing::PACKET_ID => {
|
||||
client
|
||||
.handle_unconnected_ping(server, SUnconnectedPing::read(payload)?)
|
||||
.handle_unconnected_ping(self, server, SUnconnectedPing::read(payload)?)
|
||||
.await;
|
||||
}
|
||||
SOpenConnectionRequest1::PACKET_ID => {
|
||||
client
|
||||
.handle_open_connection_1(server, SOpenConnectionRequest1::read(payload)?)
|
||||
.handle_open_connection_1(self, server, SOpenConnectionRequest1::read(payload)?)
|
||||
.await;
|
||||
}
|
||||
SOpenConnectionRequest2::PACKET_ID => {
|
||||
client
|
||||
.handle_open_connection_2(server, SOpenConnectionRequest2::read(payload)?)
|
||||
.handle_open_connection_2(self, server, SOpenConnectionRequest2::read(payload)?)
|
||||
.await;
|
||||
}
|
||||
_ => {
|
||||
log::error!("Failed to handle bedrock client packet id {packet_id}");
|
||||
log::error!("Bedrock: Received Unknown RakNet Offline packet: {packet_id}");
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -7,25 +7,46 @@ use pumpkin_protocol::{
|
||||
codec::socket_address::SocketAddress,
|
||||
};
|
||||
|
||||
use crate::{net::Client, server::Server};
|
||||
use crate::{
|
||||
net::{Client, bedrock::BedrockClientPlatform},
|
||||
server::Server,
|
||||
};
|
||||
|
||||
impl Client {
|
||||
pub async fn handle_open_connection_1(&self, server: &Server, packet: SOpenConnectionRequest1) {
|
||||
self.send_packet_now(&COpenConnectionReply1::new(
|
||||
server.server_guid,
|
||||
false,
|
||||
0,
|
||||
packet.mtu + UDP_HEADER_SIZE,
|
||||
))
|
||||
.await;
|
||||
pub async fn handle_open_connection_1(
|
||||
&self,
|
||||
bedrock: &BedrockClientPlatform,
|
||||
server: &Server,
|
||||
packet: SOpenConnectionRequest1,
|
||||
) {
|
||||
bedrock
|
||||
.send_raknet_packet_now(
|
||||
self,
|
||||
&COpenConnectionReply1::new(
|
||||
server.server_guid,
|
||||
false,
|
||||
0,
|
||||
packet.mtu + UDP_HEADER_SIZE,
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
pub async fn handle_open_connection_2(&self, server: &Server, packet: SOpenConnectionRequest2) {
|
||||
self.send_packet_now(&COpenConnectionReply2::new(
|
||||
server.server_guid,
|
||||
SocketAddress(*self.address.lock().await),
|
||||
packet.mtu,
|
||||
false,
|
||||
))
|
||||
.await;
|
||||
pub async fn handle_open_connection_2(
|
||||
&self,
|
||||
bedrock: &BedrockClientPlatform,
|
||||
server: &Server,
|
||||
packet: SOpenConnectionRequest2,
|
||||
) {
|
||||
bedrock
|
||||
.send_raknet_packet_now(
|
||||
self,
|
||||
&COpenConnectionReply2::new(
|
||||
server.server_guid,
|
||||
SocketAddress(*self.address.lock().await),
|
||||
packet.mtu,
|
||||
false,
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,18 @@ use pumpkin_protocol::{
|
||||
codec::ascii_string::AsciiString,
|
||||
};
|
||||
|
||||
use crate::{net::Client, server::Server};
|
||||
use crate::{
|
||||
net::{Client, bedrock::BedrockClientPlatform},
|
||||
server::Server,
|
||||
};
|
||||
|
||||
impl Client {
|
||||
pub async fn handle_unconnected_ping(&self, server: &Server, packet: SUnconnectedPing) {
|
||||
pub async fn handle_unconnected_ping(
|
||||
&self,
|
||||
bedrock: &BedrockClientPlatform,
|
||||
server: &Server,
|
||||
packet: SUnconnectedPing,
|
||||
) {
|
||||
let motd_string = ServerInfo {
|
||||
edition: "MCPE",
|
||||
motd_line_1: &BASIC_CONFIG.motd,
|
||||
@@ -25,12 +33,16 @@ impl Client {
|
||||
port_ipv4: 19132,
|
||||
port_ipv6: 19133,
|
||||
};
|
||||
self.send_packet_now(&CUnconnectedPong::new(
|
||||
packet.time,
|
||||
server.server_guid,
|
||||
packet.magic,
|
||||
AsciiString(format!("{motd_string}")),
|
||||
))
|
||||
.await;
|
||||
bedrock
|
||||
.send_raknet_packet_now(
|
||||
self,
|
||||
&CUnconnectedPong::new(
|
||||
packet.time,
|
||||
server.server_guid,
|
||||
packet.magic,
|
||||
AsciiString(format!("{motd_string}")),
|
||||
),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,10 +163,7 @@ impl JavaClientPlatform {
|
||||
}
|
||||
// This way players get kicked when players using client functions (e.g. poll, send_packet)
|
||||
ConnectionState::Play => client.send_packet_now(&CPlayDisconnect::new(&reason)).await,
|
||||
_ => {
|
||||
log::warn!("Can't kick in {:?} State", client.connection_state);
|
||||
return;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
log::debug!("Closing connection for {}", client.id);
|
||||
client.close();
|
||||
|
||||
@@ -158,14 +158,14 @@ impl ClientPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_packet<P: ClientPacket>(
|
||||
pub async fn write_packet<P: ClientPacket>(
|
||||
&self,
|
||||
packet: &P,
|
||||
write: impl Write,
|
||||
) -> Result<(), WritingError> {
|
||||
match self {
|
||||
Self::Java(_) => JavaClientPlatform::write_packet(packet, write),
|
||||
Self::Bedrock(_) => BedrockClientPlatform::write_packet(packet, write),
|
||||
Self::Bedrock(bedrock) => bedrock.write_game_packet(packet, write).await,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +362,7 @@ impl Client {
|
||||
{
|
||||
let mut buf = Vec::new();
|
||||
let writer = &mut buf;
|
||||
self.platform.write_packet(packet, writer).unwrap();
|
||||
self.platform.write_packet(packet, writer).await.unwrap();
|
||||
self.enqueue_packet_data(buf.into()).await;
|
||||
}
|
||||
|
||||
@@ -397,7 +397,7 @@ impl Client {
|
||||
pub async fn send_packet_now<P: ClientPacket>(&self, packet: &P) {
|
||||
let mut packet_buf = Vec::new();
|
||||
let writer = &mut packet_buf;
|
||||
self.platform.write_packet(packet, writer).unwrap();
|
||||
self.platform.write_packet(packet, writer).await.unwrap();
|
||||
self.platform.send_packet_now(self, packet_buf).await;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user