Rework movement to improve compatibility with servers using NoCheatPlus (Fixes #35)
This commit is contained in:
parent
1df78ad1c9
commit
e35a122305
|
@ -25,10 +25,8 @@ use shared::Position as BPosition;
|
||||||
use format;
|
use format;
|
||||||
|
|
||||||
pub fn add_systems(m: &mut ecs::Manager) {
|
pub fn add_systems(m: &mut ecs::Manager) {
|
||||||
// Not actually rendering related but the faster
|
|
||||||
// we can handle input the better.
|
|
||||||
let sys = MovementHandler::new(m);
|
let sys = MovementHandler::new(m);
|
||||||
m.add_render_system(sys);
|
m.add_system(sys);
|
||||||
let sys = PlayerRenderer::new(m);
|
let sys = PlayerRenderer::new(m);
|
||||||
m.add_render_system(sys);
|
m.add_render_system(sys);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +34,7 @@ pub fn add_systems(m: &mut ecs::Manager) {
|
||||||
pub fn create_local(m: &mut ecs::Manager) -> ecs::Entity {
|
pub fn create_local(m: &mut ecs::Manager) -> ecs::Entity {
|
||||||
let entity = m.create_entity();
|
let entity = m.create_entity();
|
||||||
m.add_component_direct(entity, Position::new(0.0, 0.0, 0.0));
|
m.add_component_direct(entity, Position::new(0.0, 0.0, 0.0));
|
||||||
|
m.add_component_direct(entity, TargetPosition::new(0.0, 0.0, 0.0));
|
||||||
m.add_component_direct(entity, Rotation::new(0.0, 0.0));
|
m.add_component_direct(entity, Rotation::new(0.0, 0.0));
|
||||||
m.add_component_direct(entity, Velocity::new(0.0, 0.0, 0.0));
|
m.add_component_direct(entity, Velocity::new(0.0, 0.0, 0.0));
|
||||||
m.add_component_direct(entity, Gamemode::Survival);
|
m.add_component_direct(entity, Gamemode::Survival);
|
||||||
|
@ -491,7 +490,7 @@ struct MovementHandler {
|
||||||
movement: ecs::Key<PlayerMovement>,
|
movement: ecs::Key<PlayerMovement>,
|
||||||
gravity: ecs::Key<Gravity>,
|
gravity: ecs::Key<Gravity>,
|
||||||
gamemode: ecs::Key<Gamemode>,
|
gamemode: ecs::Key<Gamemode>,
|
||||||
position: ecs::Key<Position>,
|
position: ecs::Key<TargetPosition>,
|
||||||
velocity: ecs::Key<Velocity>,
|
velocity: ecs::Key<Velocity>,
|
||||||
game_info: ecs::Key<GameInfo>,
|
game_info: ecs::Key<GameInfo>,
|
||||||
bounds: ecs::Key<Bounds>,
|
bounds: ecs::Key<Bounds>,
|
||||||
|
@ -531,8 +530,6 @@ impl ecs::System for MovementHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, m: &mut ecs::Manager, world: &mut world::World, _: &mut render::Renderer) {
|
fn update(&mut self, m: &mut ecs::Manager, world: &mut world::World, _: &mut render::Renderer) {
|
||||||
let world_entity = m.get_world();
|
|
||||||
let delta = m.get_component(world_entity, self.game_info).unwrap().delta;
|
|
||||||
for e in m.find(&self.filter) {
|
for e in m.find(&self.filter) {
|
||||||
let movement = m.get_component_mut(e, self.movement).unwrap();
|
let movement = m.get_component_mut(e, self.movement).unwrap();
|
||||||
if movement.flying && m.get_component(e, self.gravity).is_some() {
|
if movement.flying && m.get_component(e, self.gravity).is_some() {
|
||||||
|
@ -550,55 +547,54 @@ impl ecs::System for MovementHandler {
|
||||||
|
|
||||||
let player_bounds = m.get_component(e, self.bounds).unwrap().bounds;
|
let player_bounds = m.get_component(e, self.bounds).unwrap().bounds;
|
||||||
|
|
||||||
let prev_position = position.last_position;
|
let mut last_position = position.position;
|
||||||
|
|
||||||
if world.is_chunk_loaded((position.position.x as i32) >> 4, (position.position.z as i32) >> 4) {
|
if world.is_chunk_loaded((position.position.x as i32) >> 4, (position.position.z as i32) >> 4) {
|
||||||
let (forward, yaw) = movement.calculate_movement(rotation.yaw);
|
let (forward, yaw) = movement.calculate_movement(rotation.yaw);
|
||||||
let mut speed = 4.317 / 60.0;
|
let mut speed = 0.21585;
|
||||||
if movement.is_key_pressed(Keycode::LShift) {
|
if movement.is_key_pressed(Keycode::LShift) {
|
||||||
speed = 5.612 / 60.0;
|
speed = 0.2806;
|
||||||
}
|
}
|
||||||
if movement.flying {
|
if movement.flying {
|
||||||
speed *= 2.5;
|
speed *= 2.5;
|
||||||
|
|
||||||
if movement.is_key_pressed(Keycode::Space) {
|
if movement.is_key_pressed(Keycode::Space) {
|
||||||
position.position.y += speed * delta;
|
position.position.y += speed;
|
||||||
}
|
}
|
||||||
if movement.is_key_pressed(Keycode::LCtrl) {
|
if movement.is_key_pressed(Keycode::LCtrl) {
|
||||||
position.position.y -= speed * delta;
|
position.position.y -= speed;
|
||||||
}
|
}
|
||||||
} else if gravity.as_ref().map_or(false, |v| v.on_ground) {
|
} else if gravity.as_ref().map_or(false, |v| v.on_ground) {
|
||||||
if movement.is_key_pressed(Keycode::Space) {
|
if movement.is_key_pressed(Keycode::Space) && velocity.velocity.y.abs() < 0.001 {
|
||||||
velocity.velocity.y = 0.15;
|
velocity.velocity.y = 0.42;
|
||||||
} else {
|
|
||||||
velocity.velocity.y = 0.0;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
velocity.velocity.y -= 0.01 * delta;
|
velocity.velocity.y -= 0.08;
|
||||||
if velocity.velocity.y < -0.3 {
|
if velocity.velocity.y < -3.92 {
|
||||||
velocity.velocity.y = -0.3;
|
velocity.velocity.y = -3.92;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
position.position.x += forward * yaw.cos() * delta * speed;
|
velocity.velocity.y *= 0.98;
|
||||||
position.position.z -= forward * yaw.sin() * delta * speed;
|
position.position.x += forward * yaw.cos() * speed;
|
||||||
position.position.y += velocity.velocity.y * delta;
|
position.position.z -= forward * yaw.sin() * speed;
|
||||||
|
position.position.y += velocity.velocity.y;
|
||||||
|
|
||||||
if !gamemode.noclip() {
|
if !gamemode.noclip() {
|
||||||
let mut target = position.position;
|
let mut target = position.position;
|
||||||
position.position.y = position.last_position.y;
|
position.position.y = last_position.y;
|
||||||
position.position.z = position.last_position.z;
|
position.position.z = last_position.z;
|
||||||
|
|
||||||
// We handle each axis separately to allow for a sliding
|
// We handle each axis separately to allow for a sliding
|
||||||
// effect when pushing up against walls.
|
// effect when pushing up against walls.
|
||||||
|
|
||||||
let (bounds, xhit) = check_collisions(world, position, player_bounds);
|
let (bounds, xhit) = check_collisions(world, position, &last_position, player_bounds);
|
||||||
position.position.x = bounds.min.x + 0.3;
|
position.position.x = bounds.min.x + 0.3;
|
||||||
position.last_position.x = position.position.x;
|
last_position.x = position.position.x;
|
||||||
|
|
||||||
position.position.z = target.z;
|
position.position.z = target.z;
|
||||||
let (bounds, zhit) = check_collisions(world, position, player_bounds);
|
let (bounds, zhit) = check_collisions(world, position, &last_position, player_bounds);
|
||||||
position.position.z = bounds.min.z + 0.3;
|
position.position.z = bounds.min.z + 0.3;
|
||||||
position.last_position.z = position.position.z;
|
last_position.z = position.position.z;
|
||||||
|
|
||||||
// Half block jumps
|
// Half block jumps
|
||||||
// Minecraft lets you 'jump' up 0.5 blocks
|
// Minecraft lets you 'jump' up 0.5 blocks
|
||||||
|
@ -613,7 +609,7 @@ impl ecs::System for MovementHandler {
|
||||||
position.position.z = target.z;
|
position.position.z = target.z;
|
||||||
for offset in 1 .. 9 {
|
for offset in 1 .. 9 {
|
||||||
let mini = player_bounds.add_v(cgmath::Vector3::new(0.0, offset as f64 / 16.0, 0.0));
|
let mini = player_bounds.add_v(cgmath::Vector3::new(0.0, offset as f64 / 16.0, 0.0));
|
||||||
let (_, hit) = check_collisions(world, position, mini);
|
let (_, hit) = check_collisions(world, position, &last_position, mini);
|
||||||
if !hit {
|
if !hit {
|
||||||
target.y += offset as f64 / 16.0;
|
target.y += offset as f64 / 16.0;
|
||||||
ox = target.x;
|
ox = target.x;
|
||||||
|
@ -626,20 +622,20 @@ impl ecs::System for MovementHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
position.position.y = target.y;
|
position.position.y = target.y;
|
||||||
let (bounds, yhit) = check_collisions(world, position, player_bounds);
|
let (bounds, yhit) = check_collisions(world, position, &last_position, player_bounds);
|
||||||
position.position.y = bounds.min.y;
|
position.position.y = bounds.min.y;
|
||||||
position.last_position.y = position.position.y;
|
last_position.y = position.position.y;
|
||||||
if yhit {
|
if yhit {
|
||||||
velocity.velocity.y = 0.0;
|
velocity.velocity.y = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(gravity) = gravity {
|
if let Some(gravity) = gravity {
|
||||||
let ground = Aabb3::new(
|
let ground = Aabb3::new(
|
||||||
Point3::new(-0.3, -0.05, -0.3),
|
Point3::new(-0.3, -0.005, -0.3),
|
||||||
Point3::new(0.3, 0.0, 0.3)
|
Point3::new(0.3, 0.0, 0.3)
|
||||||
);
|
);
|
||||||
let prev = gravity.on_ground;
|
let prev = gravity.on_ground;
|
||||||
let (_, hit) = check_collisions(world, position, ground);
|
let (_, hit) = check_collisions(world, position, &last_position, ground);
|
||||||
gravity.on_ground = hit;
|
gravity.on_ground = hit;
|
||||||
if !prev && gravity.on_ground {
|
if !prev && gravity.on_ground {
|
||||||
movement.did_touch_ground = true;
|
movement.did_touch_ground = true;
|
||||||
|
@ -647,17 +643,15 @@ impl ecs::System for MovementHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
position.moved = position.position != prev_position;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn check_collisions(world: &world::World, position: &mut Position, bounds: Aabb3<f64>) -> (Aabb3<f64>, bool) {
|
fn check_collisions(world: &world::World, position: &mut TargetPosition, last_position: &Vector3<f64>, bounds: Aabb3<f64>) -> (Aabb3<f64>, bool) {
|
||||||
let mut bounds = bounds.add_v(position.position);
|
let mut bounds = bounds.add_v(position.position);
|
||||||
|
|
||||||
let dir = position.position - position.last_position;
|
let dir = position.position - last_position;
|
||||||
|
|
||||||
let min_x = (bounds.min.x - 1.0) as i32;
|
let min_x = (bounds.min.x - 1.0) as i32;
|
||||||
let min_y = (bounds.min.y - 1.0) as i32;
|
let min_y = (bounds.min.y - 1.0) as i32;
|
||||||
|
|
|
@ -62,6 +62,7 @@ pub struct Server {
|
||||||
gravity: ecs::Key<entity::Gravity>,
|
gravity: ecs::Key<entity::Gravity>,
|
||||||
position: ecs::Key<entity::Position>,
|
position: ecs::Key<entity::Position>,
|
||||||
target_position: ecs::Key<entity::TargetPosition>,
|
target_position: ecs::Key<entity::TargetPosition>,
|
||||||
|
velocity: ecs::Key<entity::Velocity>,
|
||||||
gamemode: ecs::Key<Gamemode>,
|
gamemode: ecs::Key<Gamemode>,
|
||||||
pub rotation: ecs::Key<entity::Rotation>,
|
pub rotation: ecs::Key<entity::Rotation>,
|
||||||
target_rotation: ecs::Key<entity::TargetRotation>,
|
target_rotation: ecs::Key<entity::TargetRotation>,
|
||||||
|
@ -292,6 +293,7 @@ impl Server {
|
||||||
gravity: entities.get_key(),
|
gravity: entities.get_key(),
|
||||||
position: entities.get_key(),
|
position: entities.get_key(),
|
||||||
target_position: entities.get_key(),
|
target_position: entities.get_key(),
|
||||||
|
velocity: entities.get_key(),
|
||||||
gamemode: entities.get_key(),
|
gamemode: entities.get_key(),
|
||||||
rotation: entities.get_key(),
|
rotation: entities.get_key(),
|
||||||
target_rotation: entities.get_key(),
|
target_rotation: entities.get_key(),
|
||||||
|
@ -458,7 +460,7 @@ impl Server {
|
||||||
if let Some(player) = self.player {
|
if let Some(player) = self.player {
|
||||||
let movement = self.entities.get_component_mut(player, self.player_movement).unwrap();
|
let movement = self.entities.get_component_mut(player, self.player_movement).unwrap();
|
||||||
let on_ground = self.entities.get_component(player, self.gravity).map_or(false, |v| v.on_ground);
|
let on_ground = self.entities.get_component(player, self.gravity).map_or(false, |v| v.on_ground);
|
||||||
let position = self.entities.get_component(player, self.position).unwrap();
|
let position = self.entities.get_component(player, self.target_position).unwrap();
|
||||||
let rotation = self.entities.get_component(player, self.rotation).unwrap();
|
let rotation = self.entities.get_component(player, self.rotation).unwrap();
|
||||||
|
|
||||||
// Force the server to know when touched the ground
|
// Force the server to know when touched the ground
|
||||||
|
@ -651,8 +653,9 @@ impl Server {
|
||||||
fn on_teleport(&mut self, teleport: packet::play::clientbound::TeleportPlayer) {
|
fn on_teleport(&mut self, teleport: packet::play::clientbound::TeleportPlayer) {
|
||||||
use std::f64::consts::PI;
|
use std::f64::consts::PI;
|
||||||
if let Some(player) = self.player {
|
if let Some(player) = self.player {
|
||||||
let position = self.entities.get_component_mut(player, self.position).unwrap();
|
let position = self.entities.get_component_mut(player, self.target_position).unwrap();
|
||||||
let rotation = self.entities.get_component_mut(player, self.rotation).unwrap();
|
let rotation = self.entities.get_component_mut(player, self.rotation).unwrap();
|
||||||
|
let velocity = self.entities.get_component_mut(player, self.velocity).unwrap();
|
||||||
|
|
||||||
position.position.x = calculate_relative_teleport(TeleportFlag::RelX, teleport.flags, position.position.x, teleport.x);
|
position.position.x = calculate_relative_teleport(TeleportFlag::RelX, teleport.flags, position.position.x, teleport.x);
|
||||||
position.position.y = calculate_relative_teleport(TeleportFlag::RelY, teleport.flags, position.position.y, teleport.y);
|
position.position.y = calculate_relative_teleport(TeleportFlag::RelY, teleport.flags, position.position.y, teleport.y);
|
||||||
|
@ -666,6 +669,16 @@ impl Server {
|
||||||
teleport.pitch as f64
|
teleport.pitch as f64
|
||||||
) - 180.0) * (PI / 180.0));
|
) - 180.0) * (PI / 180.0));
|
||||||
|
|
||||||
|
if (teleport.flags & (TeleportFlag::RelX as u8)) == 0 {
|
||||||
|
velocity.velocity.x = 0.0;
|
||||||
|
}
|
||||||
|
if (teleport.flags & (TeleportFlag::RelY as u8)) == 0 {
|
||||||
|
velocity.velocity.y = 0.0;
|
||||||
|
}
|
||||||
|
if (teleport.flags & (TeleportFlag::RelZ as u8)) == 0 {
|
||||||
|
velocity.velocity.z = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
self.write_packet(packet::play::serverbound::TeleportConfirm {
|
self.write_packet(packet::play::serverbound::TeleportConfirm {
|
||||||
teleport_id: teleport.teleport_id,
|
teleport_id: teleport.teleport_id,
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue