fix: bedrock edition and port it to 1.21.30
This commit is contained in:
parent
9c70f09360
commit
d81acb0ab1
@ -29,7 +29,7 @@ impl PacketWrite for CreativeContent<'_> {
|
||||
}
|
||||
|
||||
#[repr(i32)]
|
||||
#[expect(unused)]
|
||||
#[allow(unused)]
|
||||
enum CreativeCategory {
|
||||
Construction = 1,
|
||||
Nature = 2,
|
||||
|
||||
@ -4,14 +4,14 @@ use pumpkin_macros::packet;
|
||||
use pumpkin_util::math::{position::BlockPos, vector2::Vector2};
|
||||
|
||||
use crate::{
|
||||
codec::{bedrock_block_pos::NetworkPos, var_int::VarInt, var_uint::VarUInt},
|
||||
codec::{var_int::VarInt, var_uint::VarUInt},
|
||||
serial::PacketWrite,
|
||||
};
|
||||
|
||||
#[packet(121)]
|
||||
pub struct CNetworkChunkPublisherUpdate {
|
||||
// https://mojang.github.io/bedrock-protocol-docs/html/NetworkChunkPublisherUpdatePacket.html
|
||||
pub pos_for_view: NetworkPos,
|
||||
pub pos_for_view: BlockPos,
|
||||
// Is in blocks, not chunks!
|
||||
pub new_radius: VarUInt,
|
||||
// TODO
|
||||
@ -21,8 +21,8 @@ pub struct CNetworkChunkPublisherUpdate {
|
||||
impl CNetworkChunkPublisherUpdate {
|
||||
pub fn new(pos_for_view: BlockPos, new_radius: u32) -> Self {
|
||||
Self {
|
||||
pos_for_view: NetworkPos(pos_for_view),
|
||||
new_radius: VarUInt(new_radius),
|
||||
pos_for_view,
|
||||
new_radius: VarUInt(new_radius << 4),
|
||||
server_build_chunk_list: Vec::new(),
|
||||
}
|
||||
}
|
||||
@ -30,7 +30,7 @@ impl CNetworkChunkPublisherUpdate {
|
||||
|
||||
impl PacketWrite for CNetworkChunkPublisherUpdate {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.pos_for_view.write_signed(writer)?;
|
||||
self.pos_for_view.write(writer)?;
|
||||
self.new_radius.write(writer)?;
|
||||
|
||||
(self.server_build_chunk_list.len() as u32).write(writer)?;
|
||||
|
||||
@ -6,10 +6,10 @@ use crate::{
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(7)]
|
||||
/// https://mojang.github.io/bedrock-protocol-docs/html/ResourcePackStackPacket.html
|
||||
pub struct CResourcePackStackPacket {
|
||||
// https://mojang.github.io/bedrock-protocol-docs/html/ResourcePackStackPacket.html
|
||||
resource_pack_required: bool,
|
||||
addons_list_size: VarUInt,
|
||||
texture_pack_list_size: VarUInt,
|
||||
game_version: String,
|
||||
experiments: Experiments,
|
||||
/// When connecting to an Editor world, include the vanilla editor packs in the stack
|
||||
@ -19,14 +19,14 @@ pub struct CResourcePackStackPacket {
|
||||
impl CResourcePackStackPacket {
|
||||
pub fn new(
|
||||
resource_pack_required: bool,
|
||||
addons_list_size: VarUInt,
|
||||
texture_pack_list_size: VarUInt,
|
||||
game_version: String,
|
||||
experiments: Experiments,
|
||||
include_editor_packs: bool,
|
||||
) -> Self {
|
||||
Self {
|
||||
resource_pack_required,
|
||||
addons_list_size,
|
||||
texture_pack_list_size,
|
||||
game_version,
|
||||
experiments,
|
||||
include_editor_packs,
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
use std::io::{Error, Write};
|
||||
|
||||
use crate::serial::PacketWrite;
|
||||
use pumpkin_macros::packet;
|
||||
|
||||
use crate::serial::PacketWrite;
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
#[packet(6)]
|
||||
/// https://mojang.github.io/bedrock-protocol-docs/html/ResourcePacksInfoPacket.html
|
||||
pub struct CResourcePacksInfo {
|
||||
resource_pack_required: bool,
|
||||
has_addon_packs: bool,
|
||||
@ -12,36 +11,7 @@ pub struct CResourcePacksInfo {
|
||||
is_vibrant_visuals_force_disabled: bool,
|
||||
world_template_id: uuid::Uuid,
|
||||
world_template_version: String,
|
||||
resource_packs_size: u16,
|
||||
resource_packs: Vec<ResourcePack>,
|
||||
}
|
||||
|
||||
impl PacketWrite for CResourcePacksInfo {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.resource_pack_required.write(writer)?;
|
||||
self.has_addon_packs.write(writer)?;
|
||||
self.has_scripts.write(writer)?;
|
||||
self.is_vibrant_visuals_force_disabled.write(writer)?;
|
||||
self.world_template_id.write(writer)?;
|
||||
self.world_template_version.write(writer)?;
|
||||
self.resource_packs_size.write(writer)?;
|
||||
self.resource_packs.write(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
pub struct ResourcePack {
|
||||
pack_id: uuid::Uuid,
|
||||
version: String,
|
||||
size: u64,
|
||||
content_key: String,
|
||||
subpack_name: String,
|
||||
content_identity: String,
|
||||
has_scripts: bool,
|
||||
is_addon_pack: bool,
|
||||
is_raytracing_capable: bool,
|
||||
cdn_url: String,
|
||||
resource_packs_size: u16, // TODO: Add more
|
||||
}
|
||||
|
||||
impl CResourcePacksInfo {
|
||||
@ -52,7 +22,6 @@ impl CResourcePacksInfo {
|
||||
is_vibrant_visuals_force_disabled: bool,
|
||||
world_template_id: uuid::Uuid,
|
||||
world_template_version: String,
|
||||
resource_packs: Vec<ResourcePack>,
|
||||
) -> Self {
|
||||
Self {
|
||||
resource_pack_required,
|
||||
@ -61,8 +30,8 @@ impl CResourcePacksInfo {
|
||||
is_vibrant_visuals_force_disabled,
|
||||
world_template_id,
|
||||
world_template_version,
|
||||
resource_packs_size: resource_packs.len() as u16,
|
||||
resource_packs,
|
||||
// TODO
|
||||
resource_packs_size: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +34,6 @@ pub struct CStartGame {
|
||||
|
||||
pub current_level_time: u64,
|
||||
pub enchantment_seed: VarInt,
|
||||
|
||||
pub block_properties_size: VarUInt,
|
||||
//pub block_properties: [GG; 2],
|
||||
pub multiplayer_correlation_id: String,
|
||||
@ -51,8 +50,7 @@ pub struct CStartGame {
|
||||
|
||||
pub enable_clientside_generation: bool,
|
||||
pub blocknetwork_ids_are_hashed: bool,
|
||||
// NetworkPermissions
|
||||
pub disable_client_sounds: bool,
|
||||
pub server_auth_sounds: bool,
|
||||
}
|
||||
|
||||
#[derive(PacketWrite)]
|
||||
@ -115,7 +113,6 @@ pub struct LevelSettings {
|
||||
pub new_nether: bool,
|
||||
pub edu_shared_uri_button_name: String,
|
||||
pub edu_shared_uri_link_uri: String,
|
||||
|
||||
pub override_force_experimental_gameplay_has_value: bool,
|
||||
pub chat_restriction_level: i8,
|
||||
pub disable_player_interactions: bool,
|
||||
|
||||
@ -134,7 +134,7 @@ impl UDPNetworkDecoder {
|
||||
err => PacketDecodeError::MalformedLength(err.to_string()),
|
||||
})?;
|
||||
|
||||
let packet_len = packet_len.0 as usize;
|
||||
let packet_len = packet_len.0 as u64;
|
||||
|
||||
let var_header = VarUInt::decode(&mut reader)?;
|
||||
|
||||
@ -157,7 +157,7 @@ impl UDPNetworkDecoder {
|
||||
let gamepacket_id = (header & 0x3FF) as u16; // 0x3FF is 10 bits set to 1
|
||||
|
||||
let payload = reader
|
||||
.read_boxed_slice(packet_len - var_header.written_size())
|
||||
.read_boxed_slice(packet_len as usize - var_header.written_size())
|
||||
.map_err(|err| PacketDecodeError::FailedDecompression(err.to_string()))?;
|
||||
|
||||
Ok(RawPacket {
|
||||
|
||||
@ -1,97 +1,157 @@
|
||||
use std::io::{Error, Read, Write};
|
||||
|
||||
use pumpkin_macros::packet;
|
||||
|
||||
use crate::{
|
||||
codec::var_uint::VarUInt,
|
||||
serial::{PacketRead, PacketWrite},
|
||||
};
|
||||
use pumpkin_macros::packet;
|
||||
use std::io::{Error, ErrorKind, Read, Write};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[packet(9)]
|
||||
pub struct SText {
|
||||
// https://mojang.github.io/bedrock-protocol-docs/html/TextPacket.html
|
||||
pub needs_translation: bool,
|
||||
pub r#type: TextPacketType,
|
||||
pub localize: bool,
|
||||
pub player_name: String,
|
||||
pub source_name: String,
|
||||
pub message: String,
|
||||
pub parameters: Vec<String>,
|
||||
pub sender_xuid: String,
|
||||
pub platform_id: String,
|
||||
pub filtered_message: String,
|
||||
pub xuid: String,
|
||||
pub platform_chat_id: String,
|
||||
pub filtered_message: Option<String>,
|
||||
}
|
||||
|
||||
impl SText {
|
||||
pub fn new(message: String, player_name: String) -> Self {
|
||||
pub fn new(message: String, source_name: String) -> Self {
|
||||
Self {
|
||||
needs_translation: false,
|
||||
r#type: TextPacketType::Chat,
|
||||
localize: false,
|
||||
player_name,
|
||||
message,
|
||||
source_name,
|
||||
message: if message.is_empty() {
|
||||
" ".to_string()
|
||||
} else {
|
||||
message
|
||||
},
|
||||
parameters: Vec::new(),
|
||||
sender_xuid: String::new(),
|
||||
platform_id: String::new(),
|
||||
filtered_message: String::new(),
|
||||
xuid: String::new(),
|
||||
platform_chat_id: String::new(),
|
||||
filtered_message: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn system_message(message: String) -> Self {
|
||||
Self {
|
||||
r#type: TextPacketType::SystemMessage,
|
||||
localize: false,
|
||||
player_name: String::new(),
|
||||
message,
|
||||
needs_translation: false,
|
||||
r#type: TextPacketType::System,
|
||||
source_name: String::new(),
|
||||
message: if message.is_empty() {
|
||||
" ".to_string()
|
||||
} else {
|
||||
message
|
||||
},
|
||||
parameters: Vec::new(),
|
||||
sender_xuid: String::new(),
|
||||
platform_id: String::new(),
|
||||
filtered_message: String::new(),
|
||||
xuid: String::new(),
|
||||
platform_chat_id: String::new(),
|
||||
filtered_message: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_dummy_strings(category: u8) -> &'static [&'static str] {
|
||||
match category {
|
||||
0 => &[
|
||||
"raw",
|
||||
"tip",
|
||||
"systemMessage",
|
||||
"textObjectWhisper",
|
||||
"textObjectAnnouncement",
|
||||
"textObject",
|
||||
],
|
||||
1 => &["chat", "whisper", "announcement"],
|
||||
2 => &["translate", "popup", "jukeboxPopup"],
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
|
||||
fn get_category(&self) -> u8 {
|
||||
match self.r#type {
|
||||
TextPacketType::Raw
|
||||
| TextPacketType::Tip
|
||||
| TextPacketType::System
|
||||
| TextPacketType::JsonWhisper
|
||||
| TextPacketType::JsonAnnouncement
|
||||
| TextPacketType::Json => 0, // CATEGORY_MESSAGE_ONLY
|
||||
|
||||
TextPacketType::Chat | TextPacketType::Whisper | TextPacketType::Announcement => 1, // CATEGORY_AUTHORED_MESSAGE
|
||||
|
||||
TextPacketType::Translation | TextPacketType::Popup | TextPacketType::JukeboxPopup => 2, // CATEGORY_MESSAGE_WITH_PARAMETERS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRead for SText {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
let r#type = TextPacketType::read(reader)?;
|
||||
let localize = bool::read(reader)?;
|
||||
let needs_translation = bool::read(reader)?;
|
||||
|
||||
let mut player_name = String::new();
|
||||
let message;
|
||||
let category = u8::read(reader)?;
|
||||
|
||||
let expected_dummies = Self::get_dummy_strings(category);
|
||||
for &expected in expected_dummies {
|
||||
let actual = String::read(reader)?;
|
||||
if actual != expected {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
format!(
|
||||
"Dummy string mismatch: expected {}, got {}",
|
||||
expected, actual
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
let r#type = TextPacketType::read(reader)?;
|
||||
|
||||
let mut source_name = String::new();
|
||||
#[expect(unused)]
|
||||
let mut message = String::new();
|
||||
let mut parameters = Vec::new();
|
||||
|
||||
match r#type {
|
||||
TextPacketType::Chat | TextPacketType::Whisper | TextPacketType::Announcement => {
|
||||
source_name = String::read(reader)?;
|
||||
message = String::read(reader)?;
|
||||
}
|
||||
TextPacketType::Raw
|
||||
| TextPacketType::Tip
|
||||
| TextPacketType::SystemMessage
|
||||
| TextPacketType::TextObjectWhisper
|
||||
| TextPacketType::TextObject
|
||||
| TextPacketType::TextObjectAnnouncement => {
|
||||
| TextPacketType::System
|
||||
| TextPacketType::JsonWhisper
|
||||
| TextPacketType::Json
|
||||
| TextPacketType::JsonAnnouncement => {
|
||||
message = String::read(reader)?;
|
||||
}
|
||||
TextPacketType::Chat | TextPacketType::Whisper | TextPacketType::Announcement => {
|
||||
player_name = String::read(reader)?;
|
||||
message = String::read(reader)?;
|
||||
}
|
||||
TextPacketType::Translate | TextPacketType::Popup | TextPacketType::JukeboxPopup => {
|
||||
TextPacketType::Translation | TextPacketType::Popup | TextPacketType::JukeboxPopup => {
|
||||
message = String::read(reader)?;
|
||||
let count = VarUInt::read(reader)?.0 as usize;
|
||||
parameters = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
parameters.push(String::read(reader)?);
|
||||
}
|
||||
}
|
||||
}
|
||||
let sender_xuid = String::read(reader)?;
|
||||
let platform_id = String::read(reader)?;
|
||||
let filtered_message = String::read(reader)?;
|
||||
|
||||
let xuid = String::read(reader)?;
|
||||
let platform_chat_id = String::read(reader)?;
|
||||
|
||||
let has_filtered = bool::read(reader)?;
|
||||
let filtered_message = if has_filtered {
|
||||
Some(String::read(reader)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
needs_translation,
|
||||
r#type,
|
||||
localize,
|
||||
player_name,
|
||||
source_name,
|
||||
message,
|
||||
parameters,
|
||||
sender_xuid,
|
||||
platform_id,
|
||||
xuid,
|
||||
platform_chat_id,
|
||||
filtered_message,
|
||||
})
|
||||
}
|
||||
@ -99,22 +159,31 @@ impl PacketRead for SText {
|
||||
|
||||
impl PacketWrite for SText {
|
||||
fn write<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
|
||||
self.needs_translation.write(writer)?;
|
||||
|
||||
let category = self.get_category();
|
||||
category.write(writer)?;
|
||||
|
||||
for &dummy in Self::get_dummy_strings(category) {
|
||||
dummy.to_string().write(writer)?;
|
||||
}
|
||||
|
||||
self.r#type.write(writer)?;
|
||||
self.localize.write(writer)?;
|
||||
|
||||
match self.r#type {
|
||||
TextPacketType::Chat | TextPacketType::Whisper | TextPacketType::Announcement => {
|
||||
self.source_name.write(writer)?;
|
||||
self.message.write(writer)?;
|
||||
}
|
||||
TextPacketType::Raw
|
||||
| TextPacketType::Tip
|
||||
| TextPacketType::SystemMessage
|
||||
| TextPacketType::TextObjectWhisper
|
||||
| TextPacketType::TextObject
|
||||
| TextPacketType::TextObjectAnnouncement => {
|
||||
| TextPacketType::System
|
||||
| TextPacketType::JsonWhisper
|
||||
| TextPacketType::Json
|
||||
| TextPacketType::JsonAnnouncement => {
|
||||
self.message.write(writer)?;
|
||||
}
|
||||
TextPacketType::Chat | TextPacketType::Whisper | TextPacketType::Announcement => {
|
||||
self.player_name.write(writer)?;
|
||||
self.message.write(writer)?;
|
||||
}
|
||||
TextPacketType::Translate | TextPacketType::Popup | TextPacketType::JukeboxPopup => {
|
||||
TextPacketType::Translation | TextPacketType::Popup | TextPacketType::JukeboxPopup => {
|
||||
self.message.write(writer)?;
|
||||
VarUInt(self.parameters.len() as u32).write(writer)?;
|
||||
for param in &self.parameters {
|
||||
@ -122,47 +191,36 @@ impl PacketWrite for SText {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.sender_xuid.write(writer)?;
|
||||
self.platform_id.write(writer)?;
|
||||
self.filtered_message.write(writer)
|
||||
|
||||
self.xuid.write(writer)?;
|
||||
self.platform_chat_id.write(writer)?;
|
||||
|
||||
if let Some(msg) = &self.filtered_message {
|
||||
true.write(writer)?;
|
||||
msg.write(writer)?;
|
||||
} else {
|
||||
false.write(writer)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum TextPacketType {
|
||||
Raw = 0,
|
||||
Chat = 1,
|
||||
Translate = 2,
|
||||
Translation = 2,
|
||||
Popup = 3,
|
||||
JukeboxPopup = 4,
|
||||
Tip = 5,
|
||||
SystemMessage = 6,
|
||||
System = 6,
|
||||
Whisper = 7,
|
||||
Announcement = 8,
|
||||
TextObjectWhisper = 9,
|
||||
TextObject = 10,
|
||||
TextObjectAnnouncement = 11,
|
||||
}
|
||||
|
||||
impl PacketRead for TextPacketType {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
Ok(match u8::read(reader)? {
|
||||
0 => Self::Raw,
|
||||
1 => Self::Chat,
|
||||
2 => Self::Translate,
|
||||
3 => Self::Popup,
|
||||
4 => Self::JukeboxPopup,
|
||||
5 => Self::Tip,
|
||||
6 => Self::SystemMessage,
|
||||
7 => Self::Whisper,
|
||||
8 => Self::Announcement,
|
||||
9 => Self::TextObjectWhisper,
|
||||
10 => Self::TextObject,
|
||||
11 => Self::TextObjectAnnouncement,
|
||||
_ => return Err(Error::new(std::io::ErrorKind::InvalidData, "")),
|
||||
})
|
||||
}
|
||||
JsonWhisper = 9,
|
||||
Json = 10,
|
||||
JsonAnnouncement = 11,
|
||||
}
|
||||
|
||||
impl PacketWrite for TextPacketType {
|
||||
@ -170,3 +228,23 @@ impl PacketWrite for TextPacketType {
|
||||
(*self as u8).write(writer)
|
||||
}
|
||||
}
|
||||
|
||||
impl PacketRead for TextPacketType {
|
||||
fn read<R: Read>(reader: &mut R) -> Result<Self, Error> {
|
||||
match u8::read(reader)? {
|
||||
0 => Ok(Self::Raw),
|
||||
1 => Ok(Self::Chat),
|
||||
2 => Ok(Self::Translation),
|
||||
3 => Ok(Self::Popup),
|
||||
4 => Ok(Self::JukeboxPopup),
|
||||
5 => Ok(Self::Tip),
|
||||
6 => Ok(Self::System),
|
||||
7 => Ok(Self::Whisper),
|
||||
8 => Ok(Self::Announcement),
|
||||
9 => Ok(Self::JsonWhisper),
|
||||
10 => Ok(Self::Json),
|
||||
11 => Ok(Self::JsonAnnouncement),
|
||||
_ => Err(Error::new(ErrorKind::InvalidData, "Unknown Text Type")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ pub type BlockStateId = u16;
|
||||
pub const CURRENT_MC_VERSION: &str = "1.21.11";
|
||||
pub const LOWEST_SUPPRORTED_PROTOCOL_VERSION: u32 = 773;
|
||||
|
||||
pub const CURRENT_BEDROCK_MC_VERSION: &str = "1.21.32";
|
||||
pub const CURRENT_BEDROCK_MC_VERSION: &str = "1.21.130";
|
||||
pub const CURRENT_BEDROCK_MC_PROTOCOL: u32 = 898;
|
||||
|
||||
#[macro_export]
|
||||
|
||||
@ -1785,18 +1785,7 @@ impl Player {
|
||||
}
|
||||
|
||||
pub async fn send_system_message(&self, text: &TextComponent) {
|
||||
match &self.client {
|
||||
ClientPlatform::Java(client) => {
|
||||
client
|
||||
.enqueue_packet(&CSystemChatMessage::new(text, false))
|
||||
.await;
|
||||
}
|
||||
ClientPlatform::Bedrock(client) => {
|
||||
client
|
||||
.send_game_packet(&SText::system_message(text.clone().get_text()))
|
||||
.await;
|
||||
}
|
||||
}
|
||||
self.send_system_message_raw(text, false).await;
|
||||
}
|
||||
|
||||
pub async fn send_system_message_raw(&self, text: &TextComponent, overlay: bool) {
|
||||
@ -2508,13 +2497,6 @@ impl EntityBase for Player {
|
||||
if self.abilities.lock().await.invulnerable && damage_type != DamageType::GENERIC_KILL {
|
||||
return false;
|
||||
}
|
||||
let dyn_self = self
|
||||
.living_entity
|
||||
.entity
|
||||
.world
|
||||
.get_entity_by_id(self.living_entity.entity.entity_id)
|
||||
.await
|
||||
.expect("Entity not found in world");
|
||||
let result = self
|
||||
.living_entity
|
||||
.damage_with_context(caller, amount, damage_type, position, source, cause)
|
||||
@ -2523,8 +2505,7 @@ impl EntityBase for Player {
|
||||
let health = self.living_entity.health.load();
|
||||
if health <= 0.0 {
|
||||
let death_message =
|
||||
LivingEntity::get_death_message(&*dyn_self, damage_type, source, cause)
|
||||
.await;
|
||||
LivingEntity::get_death_message(caller, damage_type, source, cause).await;
|
||||
self.handle_killed(death_message).await;
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,14 +49,12 @@ struct CertificateChainPayload {
|
||||
|
||||
impl BedrockClient {
|
||||
pub async fn handle_request_network_settings(&self, _packet: SRequestNetworkSettings) {
|
||||
log::debug!("Bedrock: Sending Network settings");
|
||||
self.send_game_packet(&CNetworkSettings::new(0, 0, false, 0, 0.0))
|
||||
.await;
|
||||
self.set_compression(CompressionInfo::default()).await;
|
||||
}
|
||||
|
||||
pub async fn handle_login(self: &Arc<Self>, packet: SLogin, server: &Server) -> Option<()> {
|
||||
log::debug!("Bedrock: handle login");
|
||||
match self.try_handle_login(packet, server).await {
|
||||
Ok(()) => Some(()),
|
||||
Err(error) => {
|
||||
@ -103,15 +101,7 @@ impl BedrockClient {
|
||||
self.write_game_packet_to_set(&CPlayStatus::LoginSuccess, &mut frame_set)
|
||||
.await;
|
||||
self.write_game_packet_to_set(
|
||||
&CResourcePacksInfo::new(
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
uuid::Uuid::default(),
|
||||
String::new(),
|
||||
Vec::new(),
|
||||
),
|
||||
&CResourcePacksInfo::new(false, false, false, false, Uuid::default(), String::new()),
|
||||
&mut frame_set,
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -484,7 +484,6 @@ impl BedrockClient {
|
||||
packet: RawPacket,
|
||||
) -> Result<(), Error> {
|
||||
let payload = &mut Cursor::new(&packet.payload);
|
||||
log::error!("packet id {}", packet.id);
|
||||
match packet.id {
|
||||
SRequestNetworkSettings::PACKET_ID => {
|
||||
self.handle_request_network_settings(SRequestNetworkSettings::read(payload)?)
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use std::num::NonZeroU32;
|
||||
use std::pin::Pin;
|
||||
use std::sync::Weak;
|
||||
use std::sync::atomic::Ordering::Relaxed;
|
||||
@ -56,7 +57,10 @@ use pumpkin_data::{
|
||||
use pumpkin_data::{BlockDirection, BlockState};
|
||||
use pumpkin_inventory::screen_handler::InventoryPlayer;
|
||||
use pumpkin_nbt::{compound::NbtCompound, to_bytes_unnamed};
|
||||
use pumpkin_protocol::bedrock::client::chunk_radius_update::CChunkRadiusUpdate;
|
||||
use pumpkin_protocol::bedrock::client::network_chunk_publisher_update::CNetworkChunkPublisherUpdate;
|
||||
use pumpkin_protocol::bedrock::client::start_game::CStartGame;
|
||||
use pumpkin_protocol::bedrock::frame_set::FrameSet;
|
||||
use pumpkin_protocol::java::client::play::CPlayerSpawnPosition;
|
||||
use pumpkin_protocol::java::client::play::{CSetEntityMetadata, Metadata};
|
||||
use pumpkin_protocol::ser::serializer::Serializer;
|
||||
@ -1161,7 +1165,7 @@ impl World {
|
||||
self.dimension.min_y
|
||||
}
|
||||
|
||||
#[expect(clippy::too_many_lines)]
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub async fn spawn_bedrock_player(
|
||||
&self,
|
||||
base_config: &BasicConfiguration,
|
||||
@ -1249,15 +1253,15 @@ impl World {
|
||||
entity_id: VarLong(runtime_id as _),
|
||||
runtime_entity_id: VarULong(runtime_id),
|
||||
player_gamemode: player.gamemode.load(),
|
||||
position: Vector3::new(0.0, 100.0, 0.0),
|
||||
position: Vector3::new(0.0, 200.0, 0.0),
|
||||
pitch: 0.0,
|
||||
yaw: 0.0,
|
||||
level_settings,
|
||||
level_id: String::new(),
|
||||
level_name: "World".to_string(),
|
||||
level_name: "Pumpkin world".to_string(),
|
||||
premium_world_template_id: String::new(),
|
||||
is_trial: false,
|
||||
rewind_history_size: VarInt(0),
|
||||
rewind_history_size: VarInt(40),
|
||||
server_authoritative_block_breaking: false,
|
||||
current_level_time: self.level_time.lock().await.world_age as _,
|
||||
enchantment_seed: VarInt(0),
|
||||
@ -1278,10 +1282,15 @@ impl World {
|
||||
// TODO The client needs extra biome data for this
|
||||
enable_clientside_generation: false,
|
||||
blocknetwork_ids_are_hashed: false,
|
||||
disable_client_sounds: false,
|
||||
server_auth_sounds: false,
|
||||
})
|
||||
.await;
|
||||
// chunker::update_position(&player).await;
|
||||
client
|
||||
.send_game_packet(&CChunkRadiusUpdate {
|
||||
chunk_radius: VarInt(player.config.read().await.view_distance.get().into()),
|
||||
})
|
||||
.await;
|
||||
chunker::update_position(&player).await;
|
||||
client
|
||||
.send_game_packet(&CreativeContent {
|
||||
groups: &[Group {
|
||||
@ -1293,8 +1302,20 @@ impl World {
|
||||
})
|
||||
.await;
|
||||
|
||||
let mut frame_set = FrameSet::default();
|
||||
client
|
||||
.send_game_packet(&CUpdateAttributes {
|
||||
.write_game_packet_to_set(
|
||||
&CNetworkChunkPublisherUpdate::new(
|
||||
BlockPos::new(0, 200, 0),
|
||||
NonZeroU32::from(player.config.read().await.view_distance).into(),
|
||||
),
|
||||
&mut frame_set,
|
||||
)
|
||||
.await;
|
||||
|
||||
client
|
||||
.write_game_packet_to_set(
|
||||
&CUpdateAttributes {
|
||||
runtime_id: VarULong(runtime_id),
|
||||
attributes: vec![Attribute {
|
||||
min_value: 0.0,
|
||||
@ -1307,15 +1328,22 @@ impl World {
|
||||
modifiers_list_size: VarUInt(0),
|
||||
}],
|
||||
player_tick: VarULong(0),
|
||||
})
|
||||
},
|
||||
&mut frame_set,
|
||||
)
|
||||
.await;
|
||||
player.send_abilities_update().await;
|
||||
|
||||
client
|
||||
.write_game_packet_to_set(&CPlayStatus::PlayerSpawn, &mut frame_set)
|
||||
.await;
|
||||
client.send_frame_set(frame_set, 0x84).await;
|
||||
|
||||
{
|
||||
let mut abilities = player.abilities.lock().await;
|
||||
abilities.set_for_gamemode(player.gamemode.load());
|
||||
};
|
||||
|
||||
client.send_game_packet(&CPlayStatus::PlayerSpawn).await;
|
||||
player.send_abilities_update().await;
|
||||
}
|
||||
|
||||
#[expect(clippy::too_many_lines)]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user