Fix Clientbound Login

This commit is contained in:
Snowiiii 2024-08-03 11:25:38 +02:00
parent 0b4693d6d4
commit 1f041cc7db
7 changed files with 201 additions and 24 deletions

View File

@ -66,8 +66,7 @@ impl ClientPacket for CChangeDifficulty {
pub struct CLogin {
entity_id: i32,
is_hardcore: bool,
dimension_count: VarInt,
dimension_names: String,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
@ -83,7 +82,7 @@ pub struct CLogin {
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<String>, // POSITION NOT STRING
death_loc: Option<i64>, // POSITION NOT STRING
portal_cooldown: VarInt,
enforce_secure_chat: bool,
}
@ -93,8 +92,7 @@ impl CLogin {
pub fn new(
entity_id: i32,
is_hardcore: bool,
dimension_count: VarInt,
dimension_names: String,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
@ -110,14 +108,13 @@ impl CLogin {
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<String>,
death_loc: Option<i64>, // todo add block pos
portal_cooldown: VarInt,
enforce_secure_chat: bool,
) -> Self {
Self {
entity_id,
is_hardcore,
dimension_count,
dimension_names,
max_players,
view_distance,
@ -147,8 +144,7 @@ impl ClientPacket for CLogin {
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i32(self.entity_id);
bytebuf.put_bool(self.is_hardcore);
bytebuf.put_var_int(self.dimension_count);
bytebuf.put_string(&self.dimension_names);
bytebuf.put_list(&self.dimension_names, |buf, v| buf.put_string(v));
bytebuf.put_var_int(self.max_players);
bytebuf.put_var_int(self.view_distance);
bytebuf.put_var_int(self.simulated_distance);
@ -163,9 +159,13 @@ impl ClientPacket for CLogin {
bytebuf.put_bool(self.debug);
bytebuf.put_bool(self.is_flat);
bytebuf.put_bool(self.has_death_loc);
bytebuf.put_option(&self.death_dimension_name, |buf, v| buf.put_string(v));
bytebuf.put_option(&self.death_loc, |buf, v| buf.put_string(v));
if self.has_death_loc {
bytebuf.put_string(self.death_dimension_name.as_ref().unwrap());
bytebuf.put_i64(self.death_loc.unwrap());
}
bytebuf.put_var_int(self.portal_cooldown);
bytebuf.put_bool(self.enforce_secure_chat);
}
}

View File

@ -11,5 +11,3 @@ struct Decoration {
// style: Option<>
parameters: Vec<String>,
}

View File

@ -1,6 +1,5 @@
use serde::Serialize;
#[derive(Debug, Clone, Serialize)]
pub struct DamageType {
message_id: String,
@ -59,5 +58,3 @@ const NAMES: &[&str] = &[
"wither",
"wither_skull",
];

View File

@ -5,12 +5,12 @@ use paint::Painting;
use pumpkin_protocol::client::config::RegistryEntry;
use wolf::WolfVariant;
mod biomes;
mod biomes;
mod chat_type;
mod damage_type;
mod dimensions;
mod paint;
mod wolf;
mod dimensions;
mod paint;
mod wolf;
pub struct Registry {
pub registry_id: String,

View File

@ -179,7 +179,8 @@ impl ClientPacketProcessor for Client {
self.send_packet(CRegistryData::new(
&registry.registry_id,
&registry.registry_entries,
)).unwrap_or_else(|e| self.kick(&e.to_string()));
))
.unwrap_or_else(|e| self.kick(&e.to_string()));
}
// We are done with configuring

View File

@ -0,0 +1,174 @@
use crate::{
entity::player::GameMode,
protocol::{bytebuf::ByteBuffer, ClientPacket, VarInt},
};
pub struct SetHeldItem {
slot: i8,
}
impl SetHeldItem {
pub fn new(slot: i8) -> Self {
Self { slot }
}
}
impl ClientPacket for SetHeldItem {
const PACKET_ID: VarInt = 0x53;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.slot);
}
}
pub struct CPlayerAbilities {
flags: i8,
flying_speed: f32,
field_of_view: f32,
}
impl CPlayerAbilities {
pub fn new(flags: i8, flying_speed: f32, field_of_view: f32) -> Self {
Self {
flags,
flying_speed,
field_of_view,
}
}
}
impl ClientPacket for CPlayerAbilities {
const PACKET_ID: VarInt = 0x38;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i8(self.flags);
bytebuf.put_f32(self.flying_speed);
bytebuf.put_f32(self.field_of_view);
}
}
pub struct CChangeDifficulty {
difficulty: u8,
locked: bool,
}
impl CChangeDifficulty {
pub fn new(difficulty: u8, locked: bool) -> Self {
Self { difficulty, locked }
}
}
impl ClientPacket for CChangeDifficulty {
const PACKET_ID: VarInt = 0x0B;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_u8(self.difficulty);
bytebuf.put_bool(self.locked);
}
}
pub struct CLogin {
entity_id: i32,
is_hardcore: bool,
dimension_count: VarInt,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
reduced_debug_info: bool,
enabled_respawn_screen: bool,
limited_crafting: bool,
dimension_type: VarInt,
dimension_name: String,
hashed_seed: i64,
game_mode: GameMode,
previous_gamemode: GameMode,
debug: bool,
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<String>, // POSITION NOT STRING
portal_cooldown: VarInt,
enforce_secure_chat: bool,
}
impl CLogin {
#[allow(clippy::too_many_arguments)]
pub fn new(
entity_id: i32,
is_hardcore: bool,
dimension_count: VarInt,
dimension_names: Vec<String>,
max_players: VarInt,
view_distance: VarInt,
simulated_distance: VarInt,
reduced_debug_info: bool,
enabled_respawn_screen: bool,
limited_crafting: bool,
dimension_type: VarInt,
dimension_name: String,
hashed_seed: i64,
game_mode: GameMode,
previous_gamemode: GameMode,
debug: bool,
is_flat: bool,
has_death_loc: bool,
death_dimension_name: Option<String>,
death_loc: Option<String>,
portal_cooldown: VarInt,
enforce_secure_chat: bool,
) -> Self {
Self {
entity_id,
is_hardcore,
dimension_count,
dimension_names,
max_players,
view_distance,
simulated_distance,
reduced_debug_info,
enabled_respawn_screen,
limited_crafting,
dimension_type,
dimension_name,
hashed_seed,
game_mode,
previous_gamemode,
debug,
is_flat,
has_death_loc,
death_dimension_name,
death_loc,
portal_cooldown,
enforce_secure_chat,
}
}
}
impl ClientPacket for CLogin {
const PACKET_ID: VarInt = 0x2B;
fn write(&self, bytebuf: &mut ByteBuffer) {
bytebuf.put_i32(self.entity_id);
bytebuf.put_bool(self.is_hardcore);
bytebuf.put_var_int(self.dimension_count);
bytebuf.put_string_array(self.dimension_names.as_slice());
bytebuf.put_var_int(self.max_players);
bytebuf.put_var_int(self.view_distance);
bytebuf.put_var_int(self.simulated_distance);
bytebuf.put_bool(self.reduced_debug_info);
bytebuf.put_bool(self.enabled_respawn_screen);
bytebuf.put_bool(self.limited_crafting);
bytebuf.put_var_int(self.dimension_type);
bytebuf.put_string(&self.dimension_name);
bytebuf.put_i64(self.hashed_seed);
bytebuf.put_u8(self.game_mode.to_byte() as u8);
bytebuf.put_i8(self.previous_gamemode.to_byte());
bytebuf.put_bool(self.debug);
bytebuf.put_bool(self.is_flat);
bytebuf.put_bool(self.has_death_loc);
bytebuf.put_option(&self.death_dimension_name, |buf, v| buf.put_string(v));
bytebuf.put_option(&self.death_loc, |buf, v| buf.put_string(v));
bytebuf.put_var_int(self.portal_cooldown);
bytebuf.put_bool(self.enforce_secure_chat);
}
}

View File

@ -6,7 +6,10 @@ use std::{
use base64::{engine::general_purpose, Engine};
use mio::{event::Event, Poll};
use pumpkin_protocol::{
client::{config::CPluginMessage, play::CLogin},
client::{
config::CPluginMessage,
play::{ CLogin},
},
PacketError, Players, Sample, StatusResponse, VarInt, VarInt32, Version,
};
use rsa::{rand_core::OsRng, traits::PublicKeyParts, RsaPrivateKey, RsaPublicKey};
@ -90,6 +93,7 @@ impl Server {
client.poll(self, event)
}
// todo: do this in a world
pub fn spawn_player(&mut self, client: &mut Client) {
let player = Player {
entity: Entity {
@ -101,8 +105,7 @@ impl Server {
.send_packet(CLogin::new(
player.entity_id(),
self.difficulty == Difficulty::Hard,
0,
"minecraft:overworld".into(),
vec!["minecraft:overworld".into()],
self.max_players as VarInt,
8, // view distance todo
8, // sim view dinstance todo
@ -124,10 +127,14 @@ impl Server {
))
.unwrap_or_else(|e| client.kick(&e.to_string()));
dbg!("spawning player");
client.player = Some(player);
}
// todo: do this in a world
fn spawn_chunks(player: &Player) {}
// move to world
pub fn new_entity_id(&self) -> EntityId {
self.entity_id.fetch_add(1, Ordering::SeqCst)