Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
Bryntet authored Sep 7, 2024
2 parents 59a950c + 01a71d6 commit 33a5a10
Show file tree
Hide file tree
Showing 17 changed files with 345 additions and 250 deletions.
3 changes: 0 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion pumpkin-entity/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@ version.workspace = true
edition.workspace = true

[dependencies]
pumpkin-core = { path = "../pumpkin-core"}
59 changes: 0 additions & 59 deletions pumpkin-entity/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,63 +1,4 @@
use entity_type::EntityType;
use pose::EntityPose;
use pumpkin_core::math::{
get_section_cord, position::WorldPosition, vector2::Vector2, vector3::Vector3,
};

pub mod entity_type;
pub mod pose;

pub type EntityId = i32;

pub struct Entity {
pub entity_id: EntityId,
pub entity_type: EntityType,
pub pos: Vector3<f64>,
pub block_pos: WorldPosition,
pub chunk_pos: Vector2<i32>,

pub yaw: f32,
pub head_yaw: f32,
pub pitch: f32,
// TODO: Change this in diffrent poses
pub standing_eye_height: f32,
pub pose: EntityPose,
}

impl Entity {
pub fn new(entity_id: EntityId, entity_type: EntityType, standing_eye_height: f32) -> Self {
Self {
entity_id,
entity_type,
pos: Vector3::new(0.0, 0.0, 0.0),
block_pos: WorldPosition(Vector3::new(0, 0, 0)),
chunk_pos: Vector2::new(0, 0),
yaw: 0.0,
head_yaw: 0.0,
pitch: 0.0,
standing_eye_height,
pose: EntityPose::Standing,
}
}

pub fn set_pos(&mut self, x: f64, y: f64, z: f64) {
if self.pos.x != x || self.pos.y != y || self.pos.z != z {
self.pos = Vector3::new(x, y, z);
let i = x.floor() as i32;
let j = y.floor() as i32;
let k = z.floor() as i32;

let block_pos = self.block_pos.0;
if i != block_pos.x || j != block_pos.y || k != block_pos.z {
self.block_pos = WorldPosition(Vector3::new(i, j, k));

if get_section_cord(i) != self.chunk_pos.x
|| get_section_cord(k) != self.chunk_pos.z
{
self.chunk_pos =
Vector2::new(get_section_cord(block_pos.x), get_section_cord(block_pos.z));
}
}
}
}
}
4 changes: 2 additions & 2 deletions pumpkin-protocol/src/client/play/c_play_disconnect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ use serde::Serialize;
#[derive(Serialize)]
#[packet(0x1D)]
pub struct CPlayDisconnect<'a> {
reason: TextComponent<'a>,
reason: &'a TextComponent<'a>,
}

impl<'a> CPlayDisconnect<'a> {
pub fn new(reason: TextComponent<'a>) -> Self {
pub fn new(reason: &'a TextComponent<'a>) -> Self {
Self { reason }
}
}
6 changes: 6 additions & 0 deletions pumpkin-protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ impl VarInt {
pub fn decode_partial(r: &mut &[u8]) -> Result<i32, VarIntDecodeError> {
let mut val = 0;
for i in 0..Self::MAX_SIZE {
if !r.has_remaining() {
return Err(VarIntDecodeError::Incomplete);
}
let byte = r.get_u8();
val |= (i32::from(byte) & 0b01111111) << (i * 7);
if byte & 0b10000000 == 0 {
Expand Down Expand Up @@ -71,6 +74,9 @@ impl VarInt {
pub fn decode(r: &mut &[u8]) -> Result<Self, VarIntDecodeError> {
let mut val = 0;
for i in 0..Self::MAX_SIZE {
if !r.has_remaining() {
return Err(VarIntDecodeError::Incomplete);
}
let byte = r.get_u8();
val |= (i32::from(byte) & 0b01111111) << (i * 7);
if byte & 0b10000000 == 0 {
Expand Down
2 changes: 1 addition & 1 deletion pumpkin/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ impl Client {
}
// So we can also kick on errors, but generally should use Player::kick
ConnectionState::Play => {
self.try_send_packet(&CPlayDisconnect::new(TextComponent::text(reason)))
self.try_send_packet(&CPlayDisconnect::new(&TextComponent::text(reason)))
.unwrap_or_else(|_| self.close());
}
_ => {
Expand Down
101 changes: 73 additions & 28 deletions pumpkin/src/client/player_packet.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::f32::consts::PI;

use crate::{
commands::{handle_command, CommandSender},
commands::CommandSender,
entity::player::{ChatMode, Hand, Player},
server::Server,
world::player_chunker,
Expand Down Expand Up @@ -82,15 +82,27 @@ impl Player {
Self::clamp_vertical(position.feet_y),
Self::clamp_horizontal(position.z),
);
// TODO: teleport when moving > 8 block

// send new position to all other players
let on_ground = self.on_ground;
entity.on_ground = position.ground;
let on_ground = entity.on_ground;
let entity_id = entity.entity_id;
let (x, y, z) = entity.pos.into();
let (lastx, lasty, lastz) = self.last_position.into();
let world = self.world.clone();
let world = world.lock().await;

// let delta = Vector3::new(x - lastx, y - lasty, z - lastz);
// let velocity = self.velocity;

// // Player is falling down fast, we should account for that
// let max_speed = if self.fall_flying { 300.0 } else { 100.0 };

// teleport when more than 8 blocks (i guess 8 blocks)
// TODO: REPLACE * 2.0 by movement packets. see vanilla for details
// if delta.length_squared() - velocity.length_squared() > max_speed * 2.0 {
// self.teleport(x, y, z, self.entity.yaw, self.entity.pitch);
// return;
// }
// send new position to all other players
world.broadcast_packet(
&[self.client.token],
&CUpdateEntityPos::new(
Expand Down Expand Up @@ -128,11 +140,11 @@ impl Player {
Self::clamp_vertical(position_rotation.feet_y),
Self::clamp_horizontal(position_rotation.z),
);
entity.on_ground = position_rotation.ground;
entity.yaw = wrap_degrees(position_rotation.yaw) % 360.0;
entity.pitch = wrap_degrees(position_rotation.pitch).clamp(-90.0, 90.0) % 360.0;

// send new position to all other players
let on_ground = self.on_ground;
let on_ground = entity.on_ground;
let entity_id = entity.entity_id;
let (x, y, z) = entity.pos.into();
let (lastx, lasty, lastz) = self.last_position.into();
Expand All @@ -142,6 +154,20 @@ impl Player {
let world = self.world.clone();
let world = world.lock().await;

// let delta = Vector3::new(x - lastx, y - lasty, z - lastz);
// let velocity = self.velocity;

// // Player is falling down fast, we should account for that
// let max_speed = if self.fall_flying { 300.0 } else { 100.0 };

// // teleport when more than 8 blocks (i guess 8 blocks)
// // TODO: REPLACE * 2.0 by movement packets. see vanilla for details
// if delta.length_squared() - velocity.length_squared() > max_speed * 2.0 {
// self.teleport(x, y, z, yaw, pitch);
// return;
// }
// send new position to all other players

world.broadcast_packet(
&[self.client.token],
&CUpdateEntityPosRot::new(
Expand All @@ -168,10 +194,11 @@ impl Player {
return;
}
let entity = &mut self.entity;
entity.on_ground = rotation.ground;
entity.yaw = wrap_degrees(rotation.yaw) % 360.0;
entity.pitch = wrap_degrees(rotation.pitch).clamp(-90.0, 90.0) % 360.0;
// send new position to all other players
let on_ground = self.on_ground;
let on_ground = entity.on_ground;
let entity_id = entity.entity_id;
let yaw = modulus(entity.yaw * 256.0 / 360.0, 256.0);
let pitch = modulus(entity.pitch * 256.0 / 360.0, 256.0);
Expand All @@ -187,11 +214,12 @@ impl Player {
}

pub fn handle_chat_command(&mut self, server: &mut Server, command: SChatCommand) {
handle_command(&mut CommandSender::Player(self), server, &command.command);
let dispatcher = server.command_dispatcher.clone();
dispatcher.handle_command(&mut CommandSender::Player(self), server, &command.command);
}

pub fn handle_player_ground(&mut self, _server: &mut Server, ground: SSetPlayerGround) {
self.on_ground = ground.on_ground;
self.entity.on_ground = ground.on_ground;
}

pub async fn handle_player_command(&mut self, _server: &mut Server, command: SPlayerCommand) {
Expand All @@ -202,30 +230,45 @@ impl Player {
if let Some(action) = Action::from_i32(command.action.0) {
match action {
pumpkin_protocol::server::play::Action::StartSneaking => {
if !self.sneaking {
self.set_sneaking(true).await
if !self.entity.sneaking {
self.entity
.set_sneaking(&mut self.client, self.world.clone(), true)
.await
}
}
pumpkin_protocol::server::play::Action::StopSneaking => {
if self.sneaking {
self.set_sneaking(false).await
if self.entity.sneaking {
self.entity
.set_sneaking(&mut self.client, self.world.clone(), false)
.await
}
}
pumpkin_protocol::server::play::Action::LeaveBed => todo!(),
pumpkin_protocol::server::play::Action::StartSprinting => {
if !self.sprinting {
self.set_sprinting(true).await
if !self.entity.sprinting {
self.entity
.set_sprinting(&mut self.client, self.world.clone(), true)
.await
}
}
pumpkin_protocol::server::play::Action::StopSprinting => {
if self.sprinting {
self.set_sprinting(false).await
if self.entity.sprinting {
self.entity
.set_sprinting(&mut self.client, self.world.clone(), false)
.await
}
}
pumpkin_protocol::server::play::Action::StartHorseJump => todo!(),
pumpkin_protocol::server::play::Action::StopHorseJump => todo!(),
pumpkin_protocol::server::play::Action::OpenVehicleInventory => todo!(),
pumpkin_protocol::server::play::Action::StartFlyingElytra => {} // TODO
pumpkin_protocol::server::play::Action::StartFlyingElytra => {
let fall_flying = self.entity.check_fall_flying();
if self.entity.fall_flying != fall_flying {
self.entity
.set_fall_flying(&mut self.client, self.world.clone(), fall_flying)
.await;
}
} // TODO
}
} else {
self.kick(TextComponent::text("Invalid player command"))
Expand Down Expand Up @@ -320,8 +363,10 @@ impl Player {

pub async fn handle_interact(&mut self, _: &mut Server, interact: SInteract) {
let sneaking = interact.sneaking;
if self.sneaking != sneaking {
self.set_sneaking(sneaking).await;
if self.entity.sneaking != sneaking {
self.entity
.set_sneaking(&mut self.client, self.world.clone(), sneaking)
.await;
}
match ActionType::from_i32(interact.typ.0) {
Some(action) => match action {
Expand All @@ -335,27 +380,27 @@ impl Player {
let attacked_player = world.get_by_entityid(self, entity_id.0 as EntityId);
if let Some(mut player) = attacked_player {
let token = player.client.token;
let velo = player.velocity;
let velo = player.entity.velocity;
if config.protect_creative && player.gamemode == GameMode::Creative {
return;
}
if config.knockback {
let yaw = self.entity.yaw;
let strength = 1.0;
player.knockback(
player.entity.knockback(
strength * 0.5,
(yaw * (PI / 180.0)).sin() as f64,
-(yaw * (PI / 180.0)).cos() as f64,
);
let packet = &CEntityVelocity::new(
&entity_id,
player.velocity.x as f32,
player.velocity.y as f32,
player.velocity.z as f32,
velo.x as f32,
velo.y as f32,
velo.z as f32,
);
self.velocity = self.velocity.multiply(0.6, 1.0, 0.6);
self.entity.velocity = self.entity.velocity.multiply(0.6, 1.0, 0.6);

player.velocity = velo;
player.entity.velocity = velo;
player.client.send_packet(packet);
}
if config.hurt_animation {
Expand Down
26 changes: 11 additions & 15 deletions pumpkin/src/commands/cmd_help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::commands::dispatcher::InvalidTreeError::InvalidConsumptionError;
use crate::commands::dispatcher::{CommandDispatcher, InvalidTreeError};
use crate::commands::tree::{Command, CommandTree, ConsumedArgs, RawArgs};
use crate::commands::tree_builder::argument;
use crate::commands::{dispatcher_init, CommandSender, DISPATCHER};
use crate::commands::CommandSender;
use pumpkin_core::text::TextComponent;

const NAMES: [&str; 3] = ["help", "h", "?"];
Expand All @@ -11,12 +11,12 @@ const DESCRIPTION: &str = "Print a help message.";

const ARG_COMMAND: &str = "command";

fn consume_arg_command(_src: &CommandSender, args: &mut RawArgs) -> Option<String> {
let s = args.pop()?;
fn consume_arg_command(_src: &CommandSender, _args: &mut RawArgs) -> Option<String> {
// let s = args.pop()?;

let dispatcher = DISPATCHER.get_or_init(dispatcher_init);

dispatcher.get_tree(s).ok().map(|tree| tree.names[0].into())
// dispatcher.get_tree(s).ok().map(|tree| tree.names[0].into())
// TODO
None
}

fn parse_arg_command<'a>(
Expand All @@ -35,10 +35,8 @@ fn parse_arg_command<'a>(
pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> {
CommandTree::new(NAMES, DESCRIPTION)
.with_child(
argument(ARG_COMMAND, consume_arg_command).execute(&|sender, _, args| {
let dispatcher = DISPATCHER.get_or_init(dispatcher_init);

let tree = parse_arg_command(args, dispatcher)?;
argument(ARG_COMMAND, consume_arg_command).execute(&|sender, server, args| {
let tree = parse_arg_command(args, &server.command_dispatcher)?;

sender.send_message(TextComponent::text(&format!(
"{} - {} Usage: {}",
Expand All @@ -50,14 +48,12 @@ pub(crate) fn init_command_tree<'a>() -> CommandTree<'a> {
Ok(())
}),
)
.execute(&|sender, _, _args| {
let dispatcher = DISPATCHER.get_or_init(dispatcher_init);

let mut keys: Vec<&str> = dispatcher.commands.keys().copied().collect();
.execute(&|sender, server, _args| {
let mut keys: Vec<&str> = server.command_dispatcher.commands.keys().copied().collect();
keys.sort();

for key in keys {
let Command::Tree(tree) = &dispatcher.commands[key] else {
let Command::Tree(tree) = &server.command_dispatcher.commands[key] else {
continue;
};

Expand Down
Loading

0 comments on commit 33a5a10

Please sign in to comment.