Less unwraps

This commit is contained in:
Snowiiii 2024-08-28 18:52:30 +02:00
parent 0ba9b37048
commit c36b6d3464
5 changed files with 193 additions and 140 deletions

View File

@ -31,6 +31,8 @@ use super::{
/// Processes incoming Packets from the Client to the Server /// Processes incoming Packets from the Client to the Server
/// Implements the `Client` Packets /// Implements the `Client` Packets
/// NEVER TRUST THE CLIENT. HANDLE EVERY ERROR, UNWRAP/EXPECT
/// TODO: REMOVE ALL UNWRAPS
impl Client { impl Client {
pub fn handle_handshake(&mut self, _server: &mut Server, handshake: SHandShake) { pub fn handle_handshake(&mut self, _server: &mut Server, handshake: SHandShake) {
dbg!("handshake"); dbg!("handshake");

View File

@ -35,6 +35,7 @@ fn modulus(a: f32, b: f32) -> f32 {
} }
/// Handles all Play Packets send by a real Player /// Handles all Play Packets send by a real Player
/// NEVER TRUST THE CLIENT. HANDLE EVERY ERROR, UNWRAP/EXPECT ARE FORBIDDEN
impl Player { impl Player {
pub fn handle_confirm_teleport( pub fn handle_confirm_teleport(
&mut self, &mut self,
@ -205,7 +206,9 @@ impl Player {
} }
pub fn handle_swing_arm(&mut self, server: &mut Server, swing_arm: SSwingArm) { pub fn handle_swing_arm(&mut self, server: &mut Server, swing_arm: SSwingArm) {
let animation = match Hand::from_i32(swing_arm.hand.0).unwrap() { match Hand::from_i32(swing_arm.hand.0) {
Some(hand) => {
let animation = match hand {
Hand::Main => Animation::SwingMainArm, Hand::Main => Animation::SwingMainArm,
Hand::Off => Animation::SwingOffhand, Hand::Off => Animation::SwingOffhand,
}; };
@ -215,6 +218,11 @@ impl Player {
&CEntityAnimation::new(id.into(), animation as u8), &CEntityAnimation::new(id.into(), animation as u8),
) )
} }
None => {
self.kick(TextComponent::text("Invalid hand"));
}
};
}
pub fn handle_chat_message(&mut self, server: &mut Server, chat_message: SChatMessage) { pub fn handle_chat_message(&mut self, server: &mut Server, chat_message: SChatMessage) {
dbg!("got message"); dbg!("got message");
@ -226,7 +234,7 @@ impl Player {
} }
// TODO: filter message & validation // TODO: filter message & validation
let gameprofile = self.client.gameprofile.as_ref().unwrap(); let gameprofile = &self.gameprofile;
server.broadcast_packet( server.broadcast_packet(
self, self,
@ -261,22 +269,30 @@ impl Player {
&mut self, &mut self,
_server: &mut Server, _server: &mut Server,
client_information: SClientInformationPlay, client_information: SClientInformationPlay,
) {
if let (Some(main_hand), Some(chat_mode)) = (
Hand::from_i32(client_information.main_hand.into()),
ChatMode::from_i32(client_information.chat_mode.into()),
) { ) {
self.client.config = Some(PlayerConfig { self.client.config = Some(PlayerConfig {
locale: client_information.locale, locale: client_information.locale,
view_distance: client_information.view_distance, view_distance: client_information.view_distance,
chat_mode: ChatMode::from_i32(client_information.chat_mode.into()).unwrap(), chat_mode,
chat_colors: client_information.chat_colors, chat_colors: client_information.chat_colors,
skin_parts: client_information.skin_parts, skin_parts: client_information.skin_parts,
main_hand: Hand::from_i32(client_information.main_hand.into()).unwrap(), main_hand,
text_filtering: client_information.text_filtering, text_filtering: client_information.text_filtering,
server_listing: client_information.server_listing, server_listing: client_information.server_listing,
}); });
} else {
self.kick(TextComponent::text("Invalid hand or chat type"))
}
} }
pub fn handle_interact(&mut self, server: &mut Server, interact: SInteract) { pub fn handle_interact(&mut self, server: &mut Server, interact: SInteract) {
let action = ActionType::from_i32(interact.typ.0).unwrap(); match ActionType::from_i32(interact.typ.0) {
if action == ActionType::Attack { Some(action) => match action {
ActionType::Attack => {
let entity_id = interact.entity_id; let entity_id = interact.entity_id;
// TODO: do validation and stuff // TODO: do validation and stuff
let config = &server.advanced_config.pvp; let config = &server.advanced_config.pvp;
@ -325,9 +341,19 @@ impl Player {
} }
} }
} }
ActionType::Interact => {
dbg!("todo");
}
ActionType::InteractAt => {
dbg!("todo");
}
},
None => self.kick(TextComponent::text("Invalid action type")),
}
} }
pub fn handle_player_action(&mut self, server: &mut Server, player_action: SPlayerAction) { pub fn handle_player_action(&mut self, server: &mut Server, player_action: SPlayerAction) {
match Status::from_i32(player_action.status.0).unwrap() { match Status::from_i32(player_action.status.0) {
Some(status) => match status {
Status::StartedDigging => { Status::StartedDigging => {
if !self.can_interact_with_block_at(&player_action.location, 1.0) { if !self.can_interact_with_block_at(&player_action.location, 1.0) {
// TODO: maybe log? // TODO: maybe log?
@ -339,7 +365,8 @@ impl Player {
let location = player_action.location; let location = player_action.location;
// Block break & block break sound // Block break & block break sound
// TODO: currently this is always dirt replace it // TODO: currently this is always dirt replace it
server.broadcast_packet(self, &CWorldEvent::new(2001, &location, 11, false)); server
.broadcast_packet(self, &CWorldEvent::new(2001, &location, 11, false));
// AIR // AIR
server.broadcast_packet(self, &CBlockUpdate::new(&location, 0.into())); server.broadcast_packet(self, &CBlockUpdate::new(&location, 0.into()));
} }
@ -379,6 +406,8 @@ impl Player {
Status::SwapItem => { Status::SwapItem => {
dbg!("todo"); dbg!("todo");
} }
},
None => self.kick(TextComponent::text("Invalid status")),
} }
} }
@ -395,10 +424,12 @@ impl Player {
return; return;
} }
let face = BlockFace::from_i32(use_item_on.face.0).unwrap(); if let Some(face) = BlockFace::from_i32(use_item_on.face.0) {
if let Some(item) = self.inventory.held_item() { if let Some(item) = self.inventory.held_item() {
let minecraft_id = let minecraft_id = global_registry::find_minecraft_id(
global_registry::find_minecraft_id(global_registry::ITEM_REGISTRY, item.item_id) global_registry::ITEM_REGISTRY,
item.item_id,
)
.expect("All item ids are in the global registry"); .expect("All item ids are in the global registry");
if let Ok(block_state_id) = BlockId::new(minecraft_id, None) { if let Ok(block_state_id) = BlockId::new(minecraft_id, None) {
server.broadcast_packet( server.broadcast_packet(
@ -416,6 +447,9 @@ impl Player {
} }
self.client self.client
.send_packet(&CAcknowledgeBlockChange::new(use_item_on.sequence)); .send_packet(&CAcknowledgeBlockChange::new(use_item_on.sequence));
} else {
self.kick(TextComponent::text("Invalid block face"))
}
} }
pub fn handle_use_item(&mut self, _server: &mut Server, _use_item: SUseItem) { pub fn handle_use_item(&mut self, _server: &mut Server, _use_item: SUseItem) {

View File

@ -16,12 +16,11 @@ pub fn consume_arg_player(src: &CommandSender, args: &mut RawArgs) -> Option<Str
_ => { _ => {
// todo: implement any other player than sender // todo: implement any other player than sender
if let Player(player) = src { if let Player(player) = src {
if let Some(profile) = &player.client.gameprofile { let profile = &player.gameprofile;
if profile.name == s { if profile.name == s {
return Some(s.into()); return Some(s.into());
}; };
}; };
};
None None
} }
} }
@ -46,12 +45,11 @@ pub fn parse_arg_player<'a>(
_ => { _ => {
// todo: implement any other player than sender // todo: implement any other player than sender
if let Player(player) = src { if let Player(player) = src {
if let Some(profile) = &player.client.gameprofile { let profile = &player.gameprofile;
if profile.name == s { if profile.name == s {
return Ok(player); return Ok(player);
}; };
}; };
};
Err(InvalidConsumptionError(Some(s.into()))) Err(InvalidConsumptionError(Some(s.into())))
} }
} }

View File

@ -23,7 +23,11 @@ use pumpkin_protocol::{
use pumpkin_world::vector3::Vector3; use pumpkin_world::vector3::Vector3;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{client::Client, server::Server, util::boundingbox::BoundingBox}; use crate::{
client::{authentication::GameProfile, Client},
server::Server,
util::boundingbox::BoundingBox,
};
pub struct PlayerAbilities { pub struct PlayerAbilities {
pub invulnerable: bool, pub invulnerable: bool,
@ -48,6 +52,7 @@ impl Default for PlayerAbilities {
} }
pub struct Player { pub struct Player {
pub gameprofile: GameProfile,
pub client: Client, pub client: Client,
pub entity: Entity, pub entity: Entity,
// current gamemode // current gamemode
@ -79,7 +84,21 @@ pub struct Player {
impl Player { impl Player {
pub fn new(client: Client, entity_id: EntityId, gamemode: GameMode) -> Self { pub fn new(client: Client, entity_id: EntityId, gamemode: GameMode) -> Self {
let gameprofile = match client.gameprofile.clone() {
Some(profile) => profile,
None => {
log::error!("No gameprofile?. Impossible");
GameProfile {
id: uuid::Uuid::new_v4(),
name: "".to_string(),
properties: vec![],
profile_actions: None,
}
}
};
Self { Self {
gameprofile,
client, client,
entity: Entity::new(entity_id, EntityType::Player, 1.62), entity: Entity::new(entity_id, EntityType::Player, 1.62),
on_ground: false, on_ground: false,

View File

@ -143,7 +143,7 @@ impl Server {
// despawn the player // despawn the player
// todo: put this into the entitiy struct // todo: put this into the entitiy struct
let id = player.entity_id(); let id = player.entity_id();
let uuid = player.client.gameprofile.as_ref().unwrap().id; let uuid = player.gameprofile.id;
self.broadcast_packet_except( self.broadcast_packet_except(
&[&player.client.token], &[&player.client.token],
&CRemovePlayerInfo::new(1.into(), &[UUID(uuid)]), &CRemovePlayerInfo::new(1.into(), &[UUID(uuid)]),
@ -194,7 +194,7 @@ impl Server {
let yaw = 10.0; let yaw = 10.0;
let pitch = 10.0; let pitch = 10.0;
player.teleport(x, y, z, 10.0, 10.0); player.teleport(x, y, z, 10.0, 10.0);
let gameprofile = player.client.gameprofile.as_ref().unwrap(); let gameprofile = &player.gameprofile;
// first send info update to our new player, So he can see his Skin // first send info update to our new player, So he can see his Skin
// also send his info to everyone else // also send his info to everyone else
self.broadcast_packet( self.broadcast_packet(
@ -222,7 +222,7 @@ impl Server {
.filter(|c| c.0 != &player.client.token) .filter(|c| c.0 != &player.client.token)
{ {
let playerr = playerr.as_ref().lock().unwrap(); let playerr = playerr.as_ref().lock().unwrap();
let gameprofile = &playerr.client.gameprofile.as_ref().unwrap(); let gameprofile = &playerr.gameprofile;
entries.push(pumpkin_protocol::client::play::Player { entries.push(pumpkin_protocol::client::play::Player {
uuid: gameprofile.id, uuid: gameprofile.id,
actions: vec![ actions: vec![
@ -241,7 +241,7 @@ impl Server {
// Start waiting for level chunks // Start waiting for level chunks
player.client.send_packet(&CGameEvent::new(13, 0.0)); player.client.send_packet(&CGameEvent::new(13, 0.0));
let gameprofile = player.client.gameprofile.as_ref().unwrap(); let gameprofile = &player.gameprofile;
// spawn player for every client // spawn player for every client
self.broadcast_packet_except( self.broadcast_packet_except(
@ -268,7 +268,7 @@ impl Server {
for (_, existing_player) in self.current_players.iter().filter(|c| c.0 != &token) { for (_, existing_player) in self.current_players.iter().filter(|c| c.0 != &token) {
let existing_player = existing_player.as_ref().lock().unwrap(); let existing_player = existing_player.as_ref().lock().unwrap();
let entity = &existing_player.entity; let entity = &existing_player.entity;
let gameprofile = existing_player.client.gameprofile.as_ref().unwrap(); let gameprofile = &existing_player.gameprofile;
player.client.send_packet(&CSpawnEntity::new( player.client.send_packet(&CSpawnEntity::new(
existing_player.entity_id().into(), existing_player.entity_id().into(),
UUID(gameprofile.id), UUID(gameprofile.id),