From 518b6a07f86ca7074e41a90f68aa91d0b6b47fd8 Mon Sep 17 00:00:00 2001 From: iceiix <43691553+iceiix@users.noreply.github.com> Date: Sun, 21 Jun 2020 12:17:24 -0700 Subject: [PATCH] Reformat all source with cargo fmt (#335) --- README.md | 2 +- blocks/src/lib.rs | 600 ++++++----- blocks/src/material.rs | 1 - gl/build.rs | 8 +- protocol/src/format.rs | 23 +- protocol/src/item.rs | 5 +- protocol/src/lib.rs | 5 +- protocol/src/macros.rs | 2 - protocol/src/nbt/mod.rs | 6 +- protocol/src/protocol/forge.rs | 47 +- protocol/src/protocol/mod.rs | 233 +++-- protocol/src/protocol/mojang.rs | 95 +- protocol/src/protocol/packet.rs | 158 +-- protocol/src/protocol/versions.rs | 38 +- protocol/src/protocol/versions/v15w39c.rs | 2 - protocol/src/protocol/versions/v18w50a.rs | 2 - protocol/src/protocol/versions/v19w02a.rs | 2 - protocol/src/protocol/versions/v1_10_2.rs | 2 - protocol/src/protocol/versions/v1_11_2.rs | 2 - protocol/src/protocol/versions/v1_12_2.rs | 2 - protocol/src/protocol/versions/v1_13_2.rs | 2 - protocol/src/protocol/versions/v1_14.rs | 2 - protocol/src/protocol/versions/v1_14_1.rs | 2 - protocol/src/protocol/versions/v1_14_2.rs | 2 - protocol/src/protocol/versions/v1_14_3.rs | 2 - protocol/src/protocol/versions/v1_14_4.rs | 2 - protocol/src/protocol/versions/v1_15_1.rs | 2 - protocol/src/protocol/versions/v1_7_10.rs | 2 - protocol/src/protocol/versions/v1_8_9.rs | 2 - protocol/src/protocol/versions/v1_9.rs | 2 - protocol/src/protocol/versions/v1_9_2.rs | 2 - protocol/src/types/bit/map.rs | 2 +- protocol/src/types/bit/mod.rs | 4 +- protocol/src/types/bit/set.rs | 4 +- protocol/src/types/hash.rs | 2 - protocol/src/types/metadata.rs | 97 +- protocol/src/types/mod.rs | 2 +- protocol/src/types/nibble.rs | 7 +- resources/build.rs | 16 +- resources/src/lib.rs | 1 - shared/src/axis.rs | 3 +- shared/src/direction.rs | 11 +- shared/src/lib.rs | 1 - shared/src/position.rs | 9 +- src/chunk_builder.rs | 189 ++-- src/console/mod.rs | 93 +- src/ecs/mod.rs | 240 +++-- src/entity/block_entity/mod.rs | 9 +- src/entity/block_entity/sign.rs | 149 ++- src/entity/mod.rs | 29 +- src/entity/player.rs | 419 +++++--- src/entity/systems.rs | 73 +- src/gl/mod.rs | 422 ++++---- src/main.rs | 397 ++++--- src/model/liquid.rs | 73 +- src/model/mod.rs | 556 ++++++---- src/render/atlas.rs | 20 +- src/render/clouds.rs | 53 +- src/render/glsl.rs | 7 +- src/render/mod.rs | 586 +++++++---- src/render/model.rs | 181 +++- src/render/shaders.rs | 15 +- src/render/ui.rs | 269 ++--- src/resources.rs | 149 ++- src/screen/connecting.rs | 13 +- src/screen/edit_server.rs | 25 +- src/screen/login.rs | 38 +- src/screen/mod.rs | 35 +- src/screen/server_list.rs | 113 +- src/screen/settings_menu.rs | 87 +- src/server/mod.rs | 1160 +++++++++++++++------ src/server/plugin_messages.rs | 2 - src/server/sun.rs | 123 ++- src/server/target.rs | 111 +- src/settings.rs | 64 +- src/ui/logo.rs | 30 +- src/ui/mod.rs | 401 +++++-- src/world/biome.rs | 21 +- src/world/mod.rs | 562 ++++++---- src/world/storage.rs | 10 +- 80 files changed, 5282 insertions(+), 2858 deletions(-) diff --git a/README.md b/README.md index d3f06ce..106a07e 100644 --- a/README.md +++ b/README.md @@ -97,7 +97,7 @@ There are a few basic ground-rules for contributors: 1. **Non-master branches** ought to be used for ongoing work. 1. **External API changes and significant modifications** ought to be subject to an **internal pull-request** to solicit feedback from other contributors. 1. Internal pull-requests to solicit feedback are *encouraged* for any other non-trivial contribution but left to the discretion of the contributor. -1. Contributors should attempt to adhere to the prevailing code-style. +1. Contributors should attempt to adhere to the prevailing code-style. Please install and run [cargo fmt](https://github.com/rust-lang/rustfmt) before merging any changes. ### Changes to this arrangement diff --git a/blocks/src/lib.rs b/blocks/src/lib.rs index 48c8850..b5bcda8 100644 --- a/blocks/src/lib.rs +++ b/blocks/src/lib.rs @@ -1,11 +1,10 @@ - -#![recursion_limit="600"] +#![recursion_limit = "600"] extern crate steven_shared as shared; use crate::shared::{Axis, Direction, Position}; -use collision::Aabb3; use cgmath::Point3; +use collision::Aabb3; use lazy_static::lazy_static; use std::collections::HashMap; @@ -500,7 +499,7 @@ macro_rules! define_blocks { #[derive(Clone, Copy)] pub enum TintType { Default, - Color{r: u8, g: u8, b: u8}, + Color { r: u8, g: u8, b: u8 }, Grass, Foliage, } @@ -5625,59 +5624,65 @@ define_blocks! { fn can_burn(world: &W, pos: Position) -> bool { match world.get_block(pos) { - Block::Planks{..} | - Block::DoubleWoodenSlab{..} | - Block::WoodenSlab{..} | - Block::FenceGate{..} | - Block::SpruceFenceGate{..} | - Block::BirchFenceGate{..} | - Block::JungleFenceGate{..} | - Block::DarkOakFenceGate{..} | - Block::AcaciaFenceGate{..} | - Block::Fence{..} | - Block::SpruceFence{..} | - Block::BirchFence{..} | - Block::JungleFence{..} | - Block::DarkOakFence{..} | - Block::AcaciaFence{..} | - Block::OakStairs{..} | - Block::BirchStairs{..} | - Block::SpruceStairs{..} | - Block::JungleStairs{..} | - Block::AcaciaStairs{..} | - Block::DarkOakStairs{..} | - Block::Log{..} | - Block::Log2{..} | - Block::Leaves{..} | - Block::Leaves2{..} | - Block::BookShelf{..} | - Block::TNT{..} | - Block::TallGrass{..} | - Block::DoublePlant{..} | - Block::YellowFlower{..} | - Block::RedFlower{..} | - Block::DeadBush{..} | - Block::Wool{..} | - Block::Vine{..} | - Block::CoalBlock{..} | - Block::HayBlock{..} | - Block::Carpet{..} => true, + Block::Planks { .. } + | Block::DoubleWoodenSlab { .. } + | Block::WoodenSlab { .. } + | Block::FenceGate { .. } + | Block::SpruceFenceGate { .. } + | Block::BirchFenceGate { .. } + | Block::JungleFenceGate { .. } + | Block::DarkOakFenceGate { .. } + | Block::AcaciaFenceGate { .. } + | Block::Fence { .. } + | Block::SpruceFence { .. } + | Block::BirchFence { .. } + | Block::JungleFence { .. } + | Block::DarkOakFence { .. } + | Block::AcaciaFence { .. } + | Block::OakStairs { .. } + | Block::BirchStairs { .. } + | Block::SpruceStairs { .. } + | Block::JungleStairs { .. } + | Block::AcaciaStairs { .. } + | Block::DarkOakStairs { .. } + | Block::Log { .. } + | Block::Log2 { .. } + | Block::Leaves { .. } + | Block::Leaves2 { .. } + | Block::BookShelf { .. } + | Block::TNT { .. } + | Block::TallGrass { .. } + | Block::DoublePlant { .. } + | Block::YellowFlower { .. } + | Block::RedFlower { .. } + | Block::DeadBush { .. } + | Block::Wool { .. } + | Block::Vine { .. } + | Block::CoalBlock { .. } + | Block::HayBlock { .. } + | Block::Carpet { .. } => true, _ => false, } } fn is_snowy(world: &W, pos: Position) -> bool { match world.get_block(pos.shift(Direction::Up)) { - Block::Snow{..} | Block::SnowLayer{..} => true, + Block::Snow { .. } | Block::SnowLayer { .. } => true, _ => false, } } -fn can_connect_sides bool, W: WorldAccess>(world: &W, pos: Position, f: &F) -> (bool, bool, bool, bool) { - (can_connect(world, pos.shift(Direction::North), f), - can_connect(world, pos.shift(Direction::South), f), - can_connect(world, pos.shift(Direction::West), f), - can_connect(world, pos.shift(Direction::East), f)) +fn can_connect_sides bool, W: WorldAccess>( + world: &W, + pos: Position, + f: &F, +) -> (bool, bool, bool, bool) { + ( + can_connect(world, pos.shift(Direction::North), f), + can_connect(world, pos.shift(Direction::South), f), + can_connect(world, pos.shift(Direction::West), f), + can_connect(world, pos.shift(Direction::East), f), + ) } fn can_connect bool, W: WorldAccess>(world: &W, pos: Position, f: &F) -> bool { @@ -5687,28 +5692,28 @@ fn can_connect bool, W: WorldAccess>(world: &W, pos: Position, f fn can_connect_fence(block: Block) -> bool { match block { - Block::Fence{..} | - Block::SpruceFence{..} | - Block::BirchFence{..} | - Block::JungleFence{..} | - Block::DarkOakFence{..} | - Block::AcaciaFence{..} | - Block::FenceGate{..} | - Block::SpruceFenceGate{..} | - Block::BirchFenceGate{..} | - Block::JungleFenceGate{..} | - Block::DarkOakFenceGate{..} | - Block::AcaciaFenceGate{..} => true, + Block::Fence { .. } + | Block::SpruceFence { .. } + | Block::BirchFence { .. } + | Block::JungleFence { .. } + | Block::DarkOakFence { .. } + | Block::AcaciaFence { .. } + | Block::FenceGate { .. } + | Block::SpruceFenceGate { .. } + | Block::BirchFenceGate { .. } + | Block::JungleFenceGate { .. } + | Block::DarkOakFenceGate { .. } + | Block::AcaciaFenceGate { .. } => true, _ => false, } } fn can_connect_glasspane(block: Block) -> bool { match block { - Block::Glass{..} | - Block::StainedGlass{..} | - Block::GlassPane{..} | - Block::StainedGlassPane{..} => true, + Block::Glass { .. } + | Block::StainedGlass { .. } + | Block::GlassPane { .. } + | Block::StainedGlassPane { .. } => true, _ => false, } } @@ -5721,7 +5726,11 @@ fn can_connect_redstone(world: &W, pos: Position, dir: Direction let side_up = world.get_block(shift_pos.shift(Direction::Up)); let up = world.get_block(pos.shift(Direction::Up)); - if match side_up { Block::RedstoneWire{..} => true, _ => false,} && !up.get_material().should_cull_against { + if match side_up { + Block::RedstoneWire { .. } => true, + _ => false, + } && !up.get_material().should_cull_against + { return RedstoneSide::Up; } @@ -5729,71 +5738,90 @@ fn can_connect_redstone(world: &W, pos: Position, dir: Direction } let side_down = world.get_block(shift_pos.shift(Direction::Down)); - if match block { Block::RedstoneWire{..} => true, _ => false,} || match side_down { Block::RedstoneWire{..} => true, _ => false,} { + if match block { + Block::RedstoneWire { .. } => true, + _ => false, + } || match side_down { + Block::RedstoneWire { .. } => true, + _ => false, + } { return RedstoneSide::Side; } RedstoneSide::None } fn fence_gate_data(facing: Direction, in_wall: bool, open: bool, powered: bool) -> Option { - if in_wall || powered { return None; } + if in_wall || powered { + return None; + } Some(facing.horizontal_index() | (if open { 0x4 } else { 0x0 })) } fn fence_gate_offset(facing: Direction, in_wall: bool, open: bool, powered: bool) -> Option { - Some(if powered { 0 } else { 1<<0 } + - if open { 0 } else { 1<<1 } + - if in_wall { 0 } else { 1<<2 } + - facing.horizontal_offset() * (1<<3)) + Some( + if powered { 0 } else { 1 << 0 } + + if open { 0 } else { 1 << 1 } + + if in_wall { 0 } else { 1 << 2 } + + facing.horizontal_offset() * (1 << 3), + ) } fn fence_gate_collision(facing: Direction, in_wall: bool, open: bool) -> Vec> { - if open { return vec![]; } + if open { + return vec![]; + } let (min_x, min_y, min_z, max_x, max_y, max_z) = if in_wall { match facing.axis() { - Axis::Z => (0.0, 0.0, 3.0/8.0, 1.0, 13.0/16.0, 5.0/8.0), - Axis::X => (3.0/8.0, 0.0, 0.0, 5.0/8.0, 13.0/16.0, 1.0), + Axis::Z => (0.0, 0.0, 3.0 / 8.0, 1.0, 13.0 / 16.0, 5.0 / 8.0), + Axis::X => (3.0 / 8.0, 0.0, 0.0, 5.0 / 8.0, 13.0 / 16.0, 1.0), _ => unreachable!(), } } else { match facing.axis() { - Axis::Z => (0.0, 0.0, 3.0/8.0, 1.0, 1.0, 5.0/8.0), - Axis::X => (3.0/8.0, 0.0, 0.0, 5.0/8.0, 1.0, 1.0), + Axis::Z => (0.0, 0.0, 3.0 / 8.0, 1.0, 1.0, 5.0 / 8.0), + Axis::X => (3.0 / 8.0, 0.0, 0.0, 5.0 / 8.0, 1.0, 1.0), _ => unreachable!(), } }; vec![Aabb3::new( Point3::new(min_x, min_y, min_z), - Point3::new(max_x, max_y, max_z) + Point3::new(max_x, max_y, max_z), )] } fn fence_gate_update_state(world: &W, pos: Position, facing: Direction) -> bool { - if let Block::CobblestoneWall{..} = world.get_block(pos.shift(facing.clockwise())) { + if let Block::CobblestoneWall { .. } = world.get_block(pos.shift(facing.clockwise())) { return true; } - if let Block::CobblestoneWall{..} = world.get_block(pos.shift(facing.counter_clockwise())) { + if let Block::CobblestoneWall { .. } = world.get_block(pos.shift(facing.counter_clockwise())) { return true; } false } -fn door_data(facing: Direction, half: DoorHalf, hinge: Side, open: bool, powered: bool) -> Option { +fn door_data( + facing: Direction, + half: DoorHalf, + hinge: Side, + open: bool, + powered: bool, +) -> Option { match half { DoorHalf::Upper => { if facing == Direction::North && open { - Some(0x8 - | (if hinge == Side::Right { 0x1 } else { 0x0 }) - | (if powered { 0x2 } else { 0x0 })) + Some( + 0x8 | (if hinge == Side::Right { 0x1 } else { 0x0 }) + | (if powered { 0x2 } else { 0x0 }), + ) } else { None } - }, + } DoorHalf::Lower => { if hinge == Side::Left && !powered { Some(facing.clockwise().horizontal_index() | (if open { 0x4 } else { 0x0 })) @@ -5804,26 +5832,83 @@ fn door_data(facing: Direction, half: DoorHalf, hinge: Side, open: bool, powered } } -fn door_offset(facing: Direction, half: DoorHalf, hinge: Side, open: bool, powered: bool) -> Option { - Some(if powered { 0 } else { 1<<0 } + - if open { 0 } else { 1<<1 } + - if hinge == Side::Left { 0 } else { 1<<2 } + - if half == DoorHalf::Upper { 0 } else { 1<<3 } + - facing.horizontal_offset() * (1<<4)) +fn door_offset( + facing: Direction, + half: DoorHalf, + hinge: Side, + open: bool, + powered: bool, +) -> Option { + Some( + if powered { 0 } else { 1 << 0 } + + if open { 0 } else { 1 << 1 } + + if hinge == Side::Left { 0 } else { 1 << 2 } + + if half == DoorHalf::Upper { 0 } else { 1 << 3 } + + facing.horizontal_offset() * (1 << 4), + ) } - -fn update_door_state(world: &W, pos: Position, ohalf: DoorHalf, ofacing: Direction, ohinge: Side, oopen: bool, opowered: bool) -> (Direction, Side, bool, bool) { +fn update_door_state( + world: &W, + pos: Position, + ohalf: DoorHalf, + ofacing: Direction, + ohinge: Side, + oopen: bool, + opowered: bool, +) -> (Direction, Side, bool, bool) { let oy = if ohalf == DoorHalf::Upper { -1 } else { 1 }; match world.get_block(pos + (0, oy, 0)) { - Block::WoodenDoor{half, facing, hinge, open, powered} | - Block::SpruceDoor{half, facing, hinge, open, powered} | - Block::BirchDoor{half, facing, hinge, open, powered} | - Block::JungleDoor{half, facing, hinge, open, powered} | - Block::AcaciaDoor{half, facing, hinge, open, powered} | - Block::DarkOakDoor{half, facing, hinge, open, powered} | - Block::IronDoor{half, facing, hinge, open, powered} => { + Block::WoodenDoor { + half, + facing, + hinge, + open, + powered, + } + | Block::SpruceDoor { + half, + facing, + hinge, + open, + powered, + } + | Block::BirchDoor { + half, + facing, + hinge, + open, + powered, + } + | Block::JungleDoor { + half, + facing, + hinge, + open, + powered, + } + | Block::AcaciaDoor { + half, + facing, + hinge, + open, + powered, + } + | Block::DarkOakDoor { + half, + facing, + hinge, + open, + powered, + } + | Block::IronDoor { + half, + facing, + hinge, + open, + powered, + } => { if half != ohalf { if ohalf == DoorHalf::Upper { return (facing, ohinge, open, opowered); @@ -5831,8 +5916,8 @@ fn update_door_state(world: &W, pos: Position, ohalf: DoorHalf, return (ofacing, hinge, oopen, powered); } } - }, - _ => {}, + } + _ => {} } (ofacing, ohinge, oopen, opowered) @@ -5842,7 +5927,7 @@ fn door_collision(facing: Direction, hinge: Side, open: bool) -> Vec> use std::f64::consts::PI; let mut bounds = Aabb3::new( Point3::new(0.0, 0.0, 0.0), - Point3::new(1.0, 1.0, 3.0 / 16.0) + Point3::new(1.0, 1.0, 3.0 / 16.0), ); let mut angle = match facing { Direction::South => 0.0, @@ -5851,43 +5936,48 @@ fn door_collision(facing: Direction, hinge: Side, open: bool) -> Vec> Direction::East => PI * 1.5, _ => 0.0, }; - angle += if open { - PI * 0.5 - } else { - 0.0 - } * match hinge { Side::Left => 1.0, Side::Right => -1.0 }; + angle += if open { PI * 0.5 } else { 0.0 } + * match hinge { + Side::Left => 1.0, + Side::Right => -1.0, + }; let c = angle.cos(); let s = angle.sin(); let x = bounds.min.x - 0.5; let z = bounds.min.z - 0.5; - bounds.min.x = 0.5 + (x*c - z*s); - bounds.min.z = 0.5 + (z*c + x*s); + bounds.min.x = 0.5 + (x * c - z * s); + bounds.min.z = 0.5 + (z * c + x * s); let x = bounds.max.x - 0.5; let z = bounds.max.z - 0.5; - bounds.max.x = 0.5 + (x*c - z*s); - bounds.max.z = 0.5 + (z*c + x*s); + bounds.max.x = 0.5 + (x * c - z * s); + bounds.max.z = 0.5 + (z * c + x * s); vec![bounds] } fn update_repeater_state(world: &W, pos: Position, facing: Direction) -> bool { - let f = |dir| { - match world.get_block(pos.shift(dir)) { - Block::RepeaterPowered{..} => true, - _ => false, - } + let f = |dir| match world.get_block(pos.shift(dir)) { + Block::RepeaterPowered { .. } => true, + _ => false, }; f(facing.clockwise()) || f(facing.counter_clockwise()) } -fn update_double_plant_state(world: &W, pos: Position, ohalf: BlockHalf, ovariant: DoublePlantVariant) -> (BlockHalf, DoublePlantVariant) { - if ohalf != BlockHalf::Upper { return (ohalf, ovariant); } +fn update_double_plant_state( + world: &W, + pos: Position, + ohalf: BlockHalf, + ovariant: DoublePlantVariant, +) -> (BlockHalf, DoublePlantVariant) { + if ohalf != BlockHalf::Upper { + return (ohalf, ovariant); + } match world.get_block(pos.shift(Direction::Down)) { - Block::DoublePlant{variant, ..} => (ohalf, variant), + Block::DoublePlant { variant, .. } => (ohalf, variant), _ => (ohalf, ovariant), } } @@ -5909,65 +5999,65 @@ fn piston_collision(extended: bool, facing: Direction) -> Vec> { vec![Aabb3::new( Point3::new(min_x, min_y, min_z), - Point3::new(max_x, max_y, max_z) + Point3::new(max_x, max_y, max_z), )] } fn trapdoor_collision(facing: Direction, half: BlockHalf, open: bool) -> Vec> { let (min_x, min_y, min_z, max_x, max_y, max_z) = if open { match facing { - Direction::North => (0.0, 0.0, 3.0/16.0, 1.0, 1.0, 1.0), - Direction::South => (0.0, 0.0, 0.0, 1.0, 1.0, 3.0/16.0), - Direction::West => (3.0/16.0, 0.0, 0.0, 1.0, 1.0, 1.0), - Direction::East => (0.0, 0.0, 0.0, 3.0/16.0, 1.0, 1.0), + Direction::North => (0.0, 0.0, 3.0 / 16.0, 1.0, 1.0, 1.0), + Direction::South => (0.0, 0.0, 0.0, 1.0, 1.0, 3.0 / 16.0), + Direction::West => (3.0 / 16.0, 0.0, 0.0, 1.0, 1.0, 1.0), + Direction::East => (0.0, 0.0, 0.0, 3.0 / 16.0, 1.0, 1.0), _ => unreachable!(), } } else { match half { - BlockHalf::Bottom => (0.0, 0.0, 0.0, 1.0, 3.0/16.0, 1.0), - BlockHalf::Top => (0.0, 3.0/16.0, 0.0, 1.0, 1.0, 1.0), + BlockHalf::Bottom => (0.0, 0.0, 0.0, 1.0, 3.0 / 16.0, 1.0), + BlockHalf::Top => (0.0, 3.0 / 16.0, 0.0, 1.0, 1.0, 1.0), _ => unreachable!(), } }; vec![Aabb3::new( Point3::new(min_x, min_y, min_z), - Point3::new(max_x, max_y, max_z)) - ] + Point3::new(max_x, max_y, max_z), + )] } fn fence_collision(north: bool, south: bool, west: bool, east: bool) -> Vec> { let mut collision = vec![Aabb3::new( - Point3::new(3.0/8.0, 0.0, 3.0/8.0), - Point3::new(5.0/8.0, 1.5, 5.0/8.0)) - ]; + Point3::new(3.0 / 8.0, 0.0, 3.0 / 8.0), + Point3::new(5.0 / 8.0, 1.5, 5.0 / 8.0), + )]; if north { collision.push(Aabb3::new( - Point3::new(3.0/8.0, 0.0, 0.0), - Point3::new(5.0/8.0, 1.5, 3.0/8.0)) - ); + Point3::new(3.0 / 8.0, 0.0, 0.0), + Point3::new(5.0 / 8.0, 1.5, 3.0 / 8.0), + )); } if south { collision.push(Aabb3::new( - Point3::new(3.0/8.0, 0.0, 5.0/8.0), - Point3::new(5.0/8.0, 1.5, 1.0)) - ); + Point3::new(3.0 / 8.0, 0.0, 5.0 / 8.0), + Point3::new(5.0 / 8.0, 1.5, 1.0), + )); } if west { collision.push(Aabb3::new( - Point3::new(0.0, 0.0, 3.0/8.0), - Point3::new(3.0/8.0, 1.5, 5.0/8.0)) - ); + Point3::new(0.0, 0.0, 3.0 / 8.0), + Point3::new(3.0 / 8.0, 1.5, 5.0 / 8.0), + )); } if east { collision.push(Aabb3::new( - Point3::new(5.0/8.0, 0.0, 3.0/8.0), - Point3::new(1.0, 1.5, 5.0/8.0)) - ); + Point3::new(5.0 / 8.0, 0.0, 3.0 / 8.0), + Point3::new(1.0, 1.5, 5.0 / 8.0), + )); } collision @@ -5975,36 +6065,36 @@ fn fence_collision(north: bool, south: bool, west: bool, east: bool) -> Vec Vec> { let mut collision = vec![Aabb3::new( - Point3::new(7.0/16.0, 0.0, 7.0/16.0), - Point3::new(9.0/16.0, 1.0, 9.0/16.0)) - ]; + Point3::new(7.0 / 16.0, 0.0, 7.0 / 16.0), + Point3::new(9.0 / 16.0, 1.0, 9.0 / 16.0), + )]; if north { collision.push(Aabb3::new( - Point3::new(7.0/16.0, 0.0, 0.0), - Point3::new(9.0/16.0, 1.0, 9.0/16.0)) - ); + Point3::new(7.0 / 16.0, 0.0, 0.0), + Point3::new(9.0 / 16.0, 1.0, 9.0 / 16.0), + )); } if south { collision.push(Aabb3::new( - Point3::new(7.0/16.0, 0.0, 7.0/16.0), - Point3::new(9.0/16.0, 1.0, 1.0)) - ); + Point3::new(7.0 / 16.0, 0.0, 7.0 / 16.0), + Point3::new(9.0 / 16.0, 1.0, 1.0), + )); } if west { collision.push(Aabb3::new( - Point3::new(0.0, 0.0, 7.0/16.0), - Point3::new(9.0/16.0, 1.0, 9.0/16.0)) - ); + Point3::new(0.0, 0.0, 7.0 / 16.0), + Point3::new(9.0 / 16.0, 1.0, 9.0 / 16.0), + )); } if east { collision.push(Aabb3::new( - Point3::new(7.0/16.0, 0.0, 7.0/16.0), - Point3::new(1.0, 1.0, 9.0/16.0)) - ); + Point3::new(7.0 / 16.0, 0.0, 7.0 / 16.0), + Point3::new(1.0, 1.0, 9.0 / 16.0), + )); } collision @@ -6012,20 +6102,20 @@ fn pane_collision(north: bool, south: bool, east: bool, west: bool) -> Vec(world: &W, pos: Position) -> Option<(Direction, BlockHalf)> { match world.get_block(pos) { - Block::OakStairs{facing, half, ..} | - Block::StoneStairs{facing, half, ..} | - Block::BrickStairs{facing, half, ..} | - Block::StoneBrickStairs{facing, half, ..} | - Block::NetherBrickStairs{facing, half, ..} | - Block::SandstoneStairs{facing, half, ..} | - Block::SpruceStairs{facing, half, ..} | - Block::BirchStairs{facing, half, ..} | - Block::JungleStairs{facing, half, ..} | - Block::QuartzStairs{facing, half, ..} | - Block::AcaciaStairs{facing, half, ..} | - Block::DarkOakStairs{facing, half, ..} | - Block::RedSandstoneStairs{facing, half, ..} | - Block::PurpurStairs{facing, half, ..} => Some((facing, half)), + Block::OakStairs { facing, half, .. } + | Block::StoneStairs { facing, half, .. } + | Block::BrickStairs { facing, half, .. } + | Block::StoneBrickStairs { facing, half, .. } + | Block::NetherBrickStairs { facing, half, .. } + | Block::SandstoneStairs { facing, half, .. } + | Block::SpruceStairs { facing, half, .. } + | Block::BirchStairs { facing, half, .. } + | Block::JungleStairs { facing, half, .. } + | Block::QuartzStairs { facing, half, .. } + | Block::AcaciaStairs { facing, half, .. } + | Block::DarkOakStairs { facing, half, .. } + | Block::RedSandstoneStairs { facing, half, .. } + | Block::PurpurStairs { facing, half, .. } => Some((facing, half)), _ => None, } } @@ -6054,18 +6144,34 @@ fn update_stair_shape(world: &W, pos: Position, facing: Directio StairShape::Straight } -fn stair_data(facing: Direction, half: BlockHalf, shape: StairShape, waterlogged: bool) -> Option { - if shape != StairShape::Straight { return None; } - if waterlogged { return None; } +fn stair_data( + facing: Direction, + half: BlockHalf, + shape: StairShape, + waterlogged: bool, +) -> Option { + if shape != StairShape::Straight { + return None; + } + if waterlogged { + return None; + } Some((5 - facing.index()) | (if half == BlockHalf::Top { 0x4 } else { 0x0 })) } -fn stair_offset(facing: Direction, half: BlockHalf, shape: StairShape, waterlogged: bool) -> Option { - Some(if waterlogged { 0 } else { 1 } + - shape.offset() * 2 + - if half == BlockHalf::Top { 0 } else { 2 * 5 } + - facing.horizontal_offset() * 2 * 5 * 2) +fn stair_offset( + facing: Direction, + half: BlockHalf, + shape: StairShape, + waterlogged: bool, +) -> Option { + Some( + if waterlogged { 0 } else { 1 } + + shape.offset() * 2 + + if half == BlockHalf::Top { 0 } else { 2 * 5 } + + facing.horizontal_offset() * 2 * 5 * 2, + ) } #[allow(clippy::many_single_char_names)] @@ -6113,24 +6219,24 @@ fn stair_collision(facing: Direction, shape: StairShape, half: BlockHalf) -> Vec for bound in &mut bounds { let x = bound.min.x - 0.5; let z = bound.min.z - 0.5; - bound.min.x = 0.5 + (x*c - z*s); - bound.min.z = 0.5 + (z*c + x*s); + bound.min.x = 0.5 + (x * c - z * s); + bound.min.z = 0.5 + (z * c + x * s); let x = bound.max.x - 0.5; let z = bound.max.z - 0.5; - bound.max.x = 0.5 + (x*c - z*s); - bound.max.z = 0.5 + (z*c + x*s); + bound.max.x = 0.5 + (x * c - z * s); + bound.max.z = 0.5 + (z * c + x * s); if half == BlockHalf::Top { let c = PI.cos(); let s = PI.sin(); let z = bound.min.z - 0.5; let y = bound.min.y - 0.5; - bound.min.z = 0.5 + (z*c - y*s); - bound.min.y = 0.5 + (y*c + z*s); + bound.min.z = 0.5 + (z * c - y * s); + bound.min.y = 0.5 + (y * c + z * s); let z = bound.max.z - 0.5; let y = bound.max.y - 0.5; - bound.max.z = 0.5 + (z*c - y*s); - bound.max.y = 0.5 + (y*c + z*s); + bound.max.z = 0.5 + (z * c - y * s); + bound.max.y = 0.5 + (y * c + z * s); bound.min.x = 1.0 - bound.min.x; bound.max.x = 1.0 - bound.max.x; @@ -6150,7 +6256,7 @@ fn slab_collision(half: BlockHalf) -> Vec> { vec![Aabb3::new( Point3::new(min_x, min_y, min_z), - Point3::new(max_x, max_y, max_z) + Point3::new(max_x, max_y, max_z), )] } @@ -6218,7 +6324,7 @@ impl DirtVariant { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum BedPart { Head, - Foot + Foot, } impl BedPart { @@ -6301,7 +6407,6 @@ impl NoteBlockInstrument { } } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum RedSandstoneVariant { Normal, @@ -6382,67 +6487,91 @@ impl PrismarineVariant { } } -fn mushroom_block_data(is_stem: bool, west: bool, up: bool, south: bool, north: bool, east: bool, down: bool) -> Option { - Some(match - (is_stem, west, up, south, north, east, down) { +fn mushroom_block_data( + is_stem: bool, + west: bool, + up: bool, + south: bool, + north: bool, + east: bool, + down: bool, +) -> Option { + Some(match (is_stem, west, up, south, north, east, down) { (false, false, false, false, false, false, false) => 0, - (false, true, false, false, true, false, false) => 1, - (false, false, false, false, true, false, false) => 2, - (false, false, false, false, true, true, false) => 3, - (false, true, false, false, false, false, false) => 4, - (false, false, true, false, false, false, false) => 5, - (false, false, false, false, false, true, false) => 6, - (false, true, false, true, false, false, false) => 7, - (false, false, false, true, false, false, false) => 8, - (false, false, false, true, false, true, false) => 9, - (false, true, false, true, true, true, false) => 10, - (false, true, true, true, true, true, true) => 14, - (true, false, false, false, false, false, false) => 15, + (false, true, false, false, true, false, false) => 1, + (false, false, false, false, true, false, false) => 2, + (false, false, false, false, true, true, false) => 3, + (false, true, false, false, false, false, false) => 4, + (false, false, true, false, false, false, false) => 5, + (false, false, false, false, false, true, false) => 6, + (false, true, false, true, false, false, false) => 7, + (false, false, false, true, false, false, false) => 8, + (false, false, false, true, false, true, false) => 9, + (false, true, false, true, true, true, false) => 10, + (false, true, true, true, true, true, true) => 14, + (true, false, false, false, false, false, false) => 15, _ => return None, }) } -fn mushroom_block_offset(is_stem: bool, west: bool, up: bool, south: bool, north: bool, east: bool, down: bool) -> Option { +fn mushroom_block_offset( + is_stem: bool, + west: bool, + up: bool, + south: bool, + north: bool, + east: bool, + down: bool, +) -> Option { if is_stem { None } else { - Some(if west { 0 } else { 1<<0 } + - if up { 0 } else { 1<<1 } + - if south { 0 } else { 1<<2 } + - if north { 0 } else { 1<<3 } + - if east { 0 } else { 1<<4 } + - if down { 0 } else { 1<<5 }) + Some( + if west { 0 } else { 1 << 0 } + + if up { 0 } else { 1 << 1 } + + if south { 0 } else { 1 << 2 } + + if north { 0 } else { 1 << 3 } + + if east { 0 } else { 1 << 4 } + + if down { 0 } else { 1 << 5 }, + ) } } - -fn mushroom_block_variant(is_stem: bool, west: bool, up: bool, south: bool, north: bool, east: bool, down: bool) -> String { +fn mushroom_block_variant( + is_stem: bool, + west: bool, + up: bool, + south: bool, + north: bool, + east: bool, + down: bool, +) -> String { (if is_stem { "all_stem" } else { - match - (west, up, south, north, east, down) { + match (west, up, south, north, east, down) { (false, false, false, false, false, false) => "all_inside", - (true, false, false, true, false, false) => "north_west", - (false, false, false, true, false, false) => "north", - (false, false, false, true, true, false) => "north_east", - (true, false, false, false, false, false) => "west", - (false, true, false, false, false, false) => "center", - (false, false, false, false, true, false) => "east", - (true, false, true, false, false, false) => "south_west", - (false, false, true, false, false, false) => "south", - (false, false, true, false, true, false) => "south_east", - (true, false, true, true, true, false) => "stem", - (true, true, true, true, true, true) => "all_outside", + (true, false, false, true, false, false) => "north_west", + (false, false, false, true, false, false) => "north", + (false, false, false, true, true, false) => "north_east", + (true, false, false, false, false, false) => "west", + (false, true, false, false, false, false) => "center", + (false, false, false, false, true, false) => "east", + (true, false, true, false, false, false) => "south_west", + (false, false, true, false, false, false) => "south", + (false, false, true, false, true, false) => "south_east", + (true, false, true, true, true, false) => "stem", + (true, true, true, true, true, true) => "all_outside", _ => "all_stem", } - }).to_string() + }) + .to_string() } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum DoorHalf { Upper, - Lower + Lower, } impl DoorHalf { @@ -6771,9 +6900,9 @@ impl StoneSlabVariant { fn data(self) -> usize { match self { - StoneSlabVariant::Stone | - StoneSlabVariant::RedSandstone | - StoneSlabVariant::Purpur => 0, + StoneSlabVariant::Stone | StoneSlabVariant::RedSandstone | StoneSlabVariant::Purpur => { + 0 + } StoneSlabVariant::Sandstone => 1, StoneSlabVariant::PetrifiedWood => 2, StoneSlabVariant::Cobblestone => 3, @@ -7037,7 +7166,8 @@ impl AttachedFace { (AttachedFace::Floor, Direction::East) => "up_x", (AttachedFace::Ceiling, Direction::South) => "down_z", _ => "north", // TODO: support 1.13.2+ new directions - }.to_owned() + } + .to_owned() } } @@ -7094,7 +7224,6 @@ impl StructureBlockMode { } } - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum TreeVariant { Oak, @@ -7125,7 +7254,7 @@ impl TreeVariant { TreeVariant::StrippedJungle => "stripped_jungle_log", TreeVariant::StrippedAcacia => "stripped_acacia_log", TreeVariant::StrippedDarkOak => "stripped_dark_oak_log", - TreeVariant::StrippedOak => "stripped_oak_log" + TreeVariant::StrippedOak => "stripped_oak_log", } } @@ -7388,4 +7517,3 @@ impl CoralVariant { } } } - diff --git a/blocks/src/material.rs b/blocks/src/material.rs index a809bab..b91e6ee 100644 --- a/blocks/src/material.rs +++ b/blocks/src/material.rs @@ -1,4 +1,3 @@ - pub struct Material { pub renderable: bool, pub should_cull_against: bool, diff --git a/gl/build.rs b/gl/build.rs index 4cfe3d6..2ede032 100644 --- a/gl/build.rs +++ b/gl/build.rs @@ -1,19 +1,15 @@ +use gl_generator::{Api, Fallbacks, GlobalGenerator, Profile, Registry}; use std::env; use std::fs::File; use std::io::BufWriter; use std::path::Path; -use gl_generator::{Registry, Api, Profile, Fallbacks, GlobalGenerator}; fn main() { let out_dir = env::var("OUT_DIR").unwrap(); let dest = Path::new(&out_dir); let mut file = BufWriter::new(File::create(&dest.join("bindings.rs")).unwrap()); - Registry::new(Api::Gl, - (3, 2), - Profile::Core, - Fallbacks::All, - []) + Registry::new(Api::Gl, (3, 2), Profile::Core, Fallbacks::All, []) .write_bindings(GlobalGenerator, &mut file) .unwrap(); } diff --git a/protocol/src/format.rs b/protocol/src/format.rs index 29776bd..aed2080 100644 --- a/protocol/src/format.rs +++ b/protocol/src/format.rs @@ -22,7 +22,6 @@ pub enum Component { } impl Component { - pub fn from_string(str: &str) -> Self { let mut component; match serde_json::from_str::(str) { @@ -31,7 +30,7 @@ impl Component { Err(_) => { component = Component::Text(TextComponent::new(str)); convert_legacy(&mut component); - }, + } } component } @@ -47,7 +46,9 @@ impl Component { Component::Text(TextComponent::from_value(v, modifier)) } else if v.get("translate").is_some() { // TODO: translations - Component::Text(TextComponent::new(v.get("translate").unwrap().as_str().unwrap())) + Component::Text(TextComponent::new( + v.get("translate").unwrap().as_str().unwrap(), + )) } else { modifier.color = Some(Color::RGB(255, 0, 0)); Component::Text(TextComponent { @@ -100,9 +101,10 @@ impl Modifier { underlined: v.get("underlined").map_or(Option::None, |v| v.as_bool()), strikethrough: v.get("strikethrough").map_or(Option::None, |v| v.as_bool()), obfuscated: v.get("obfuscated").map_or(Option::None, |v| v.as_bool()), - color: v.get("color") - .map_or(Option::None, |v| v.as_str()) - .map(|v| Color::from_string(&v.to_owned())), + color: v + .get("color") + .map_or(Option::None, |v| v.as_str()) + .map(|v| Color::from_string(&v.to_owned())), extra: Option::None, }; if let Some(extra) = v.get("extra") { @@ -132,7 +134,9 @@ impl TextComponent { pub fn new(val: &str) -> TextComponent { TextComponent { text: val.to_owned(), - modifier: Modifier { ..Default::default() }, + modifier: Modifier { + ..Default::default() + }, } } @@ -319,8 +323,9 @@ pub fn convert_legacy(c: &mut Component) { current.text = txt.text[last..i].to_owned(); last = next.0 + 1; - let mut modifier = if (color_char >= 'a' && color_char <= 'f') || - (color_char >= '0' && color_char <= '9') { + let mut modifier = if (color_char >= 'a' && color_char <= 'f') + || (color_char >= '0' && color_char <= '9') + { Default::default() } else { current.modifier.clone() diff --git a/protocol/src/item.rs b/protocol/src/item.rs index 8aa6ab4..7d797ed 100644 --- a/protocol/src/item.rs +++ b/protocol/src/item.rs @@ -14,8 +14,8 @@ use crate::nbt; use crate::protocol::{self, Serializable}; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use std::io; -use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt}; #[derive(Debug)] pub struct Stack { @@ -25,7 +25,6 @@ pub struct Stack { tag: Option, } - impl Default for Stack { fn default() -> Stack { Stack { @@ -44,7 +43,7 @@ impl Serializable for Option { if protocol_version >= 404 { let present = buf.read_u8()? != 0; if !present { - return Ok(None) + return Ok(None); } } diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index fe136eb..d29b9d1 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -1,10 +1,9 @@ - -#![recursion_limit="300"] +#![recursion_limit = "300"] #[macro_use] pub mod macros; -pub mod item; pub mod format; +pub mod item; pub mod nbt; pub mod protocol; pub mod types; diff --git a/protocol/src/macros.rs b/protocol/src/macros.rs index bf2b7a2..3c9b47b 100644 --- a/protocol/src/macros.rs +++ b/protocol/src/macros.rs @@ -1,5 +1,3 @@ - - #[doc(hidden)] #[macro_export] macro_rules! create_ids { diff --git a/protocol/src/nbt/mod.rs b/protocol/src/nbt/mod.rs index 37c3eca..72fce8b 100644 --- a/protocol/src/nbt/mod.rs +++ b/protocol/src/nbt/mod.rs @@ -16,9 +16,9 @@ use std::collections::HashMap; use std::io; use std::io::Read; -use super::protocol::Serializable; use super::protocol; -use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt}; +use super::protocol::Serializable; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; #[derive(Debug, Clone)] pub enum Tag { @@ -41,7 +41,6 @@ pub enum Tag { pub struct NamedTag(pub String, pub Tag); impl Tag { - pub fn new_compound() -> Tag { Tag::Compound(HashMap::new()) } @@ -163,7 +162,6 @@ impl Tag { } } - fn internal_id(&self) -> u8 { match *self { Tag::End => 0, diff --git a/protocol/src/protocol/forge.rs b/protocol/src/protocol/forge.rs index c3096e1..f9526e4 100644 --- a/protocol/src/protocol/forge.rs +++ b/protocol/src/protocol/forge.rs @@ -1,10 +1,9 @@ - -/// Implements https://wiki.vg/Minecraft_Forge_Handshake -use std::io; use byteorder::WriteBytesExt; use log::debug; +/// Implements https://wiki.vg/Minecraft_Forge_Handshake +use std::io; -use super::{Serializable, Error, LenPrefixed, VarInt}; +use super::{Error, LenPrefixed, Serializable, VarInt}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Phase { @@ -45,7 +44,6 @@ impl Serializable for Phase { } } - #[derive(Clone, Debug, Default)] pub struct ForgeMod { pub modid: String, @@ -133,19 +131,20 @@ impl Serializable for FmlHs { None }; - debug!("FML|HS ServerHello: fml_protocol_version={}, override_dimension={:?}", fml_protocol_version, override_dimension); + debug!( + "FML|HS ServerHello: fml_protocol_version={}, override_dimension={:?}", + fml_protocol_version, override_dimension + ); Ok(FmlHs::ServerHello { fml_protocol_version, override_dimension, }) - }, + } 1 => panic!("Received unexpected FML|HS ClientHello from server"), - 2 => { - Ok(FmlHs::ModList { - mods: Serializable::read_from(buf)?, - }) - }, + 2 => Ok(FmlHs::ModList { + mods: Serializable::read_from(buf)?, + }), 3 => { let protocol_version = super::current_protocol_version(); @@ -161,34 +160,34 @@ impl Serializable for FmlHs { Ok(FmlHs::ModIdData { mappings: Serializable::read_from(buf)?, block_substitutions: Serializable::read_from(buf)?, - item_substitutions: Serializable::read_from(buf)?, + item_substitutions: Serializable::read_from(buf)?, }) } - }, - 255 => { - Ok(FmlHs::HandshakeAck { - phase: Serializable::read_from(buf)?, - }) - }, + } + 255 => Ok(FmlHs::HandshakeAck { + phase: Serializable::read_from(buf)?, + }), _ => panic!("Unhandled FML|HS packet: discriminator={}", discriminator), } } fn write_to(&self, buf: &mut W) -> Result<(), Error> { match self { - FmlHs::ClientHello { fml_protocol_version } => { + FmlHs::ClientHello { + fml_protocol_version, + } => { buf.write_u8(1)?; fml_protocol_version.write_to(buf) - }, + } FmlHs::ModList { mods } => { buf.write_u8(2)?; mods.write_to(buf) - }, + } FmlHs::HandshakeAck { phase } => { buf.write_u8(255)?; phase.write_to(buf) - }, - _ => unimplemented!() + } + _ => unimplemented!(), } } } diff --git a/protocol/src/protocol/mod.rs b/protocol/src/protocol/mod.rs index 24cc79b..6461200 100644 --- a/protocol/src/protocol/mod.rs +++ b/protocol/src/protocol/mod.rs @@ -16,34 +16,36 @@ #![allow(non_camel_case_types)] use aes::Aes128; -use cfb8::Cfb8; use cfb8::stream_cipher::{NewStreamCipher, StreamCipher}; -use serde_json; -use std_or_web::fs; +use cfb8::Cfb8; +use hex; #[cfg(not(target_arch = "wasm32"))] use reqwest; -use hex; +use serde_json; +use std_or_web::fs; -pub mod mojang; pub mod forge; +pub mod mojang; -use crate::nbt; use crate::format; -use std::fmt; -use std::default; -use std::net::TcpStream; -use std::io; -use std::io::{Write, Read}; -use std::convert; -use std::sync::atomic::{AtomicBool, AtomicI32, Ordering}; -use byteorder::{BigEndian, WriteBytesExt, ReadBytesExt}; +use crate::nbt; +use crate::shared::Position; +use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; use flate2::read::{ZlibDecoder, ZlibEncoder}; use flate2::Compression; -use std::time::{Instant, Duration}; -use crate::shared::Position; use log::debug; +use std::convert; +use std::default; +use std::fmt; +use std::io; +use std::io::{Read, Write}; +use std::net::TcpStream; +use std::sync::atomic::{AtomicBool, AtomicI32, Ordering}; +use std::time::{Duration, Instant}; -pub const SUPPORTED_PROTOCOLS: [i32; 18] = [575, 498, 490, 485, 480, 477, 452, 451, 404, 340, 316, 315, 210, 109, 107, 74, 47, 5]; +pub const SUPPORTED_PROTOCOLS: [i32; 18] = [ + 575, 498, 490, 485, 480, 477, 452, 451, 404, 340, 316, 315, 210, 109, 107, 74, 47, 5, +]; static CURRENT_PROTOCOL_VERSION: AtomicI32 = AtomicI32::new(SUPPORTED_PROTOCOLS[0]); static NETWORK_DEBUG: AtomicBool = AtomicBool::new(false); @@ -233,7 +235,7 @@ impl Serializable for Vec { } } -impl Serializable for Option{ +impl Serializable for Option { fn read_from(buf: &mut R) -> Result, Error> { let ty = buf.read_u8()?; if ty == 0 { @@ -257,7 +259,10 @@ impl Serializable for Option{ } } -impl Serializable for Option where T : Serializable { +impl Serializable for Option +where + T: Serializable, +{ fn read_from(buf: &mut R) -> Result, Error> { Result::Ok(Some(T::read_from(buf)?)) } @@ -318,11 +323,7 @@ impl Serializable for bool { Result::Ok(buf.read_u8()? != 0) } fn write_to(&self, buf: &mut W) -> Result<(), Error> { - buf.write_u8(if *self { - 1 - } else { - 0 - })?; + buf.write_u8(if *self { 1 } else { 0 })?; Result::Ok(()) } } @@ -433,9 +434,9 @@ impl UUID { parts.extend_from_slice(&hex::decode(&s[24..36]).unwrap()); let mut high = 0u64; let mut low = 0u64; - for i in 0 .. 8 { - high |= (parts[i] as u64) << (56 - i*8); - low |= (parts[i + 8] as u64) << (56 - i*8); + for i in 0..8 { + high |= (parts[i] as u64) << (56 - i * 8); + low |= (parts[i + 8] as u64) << (56 - i * 8); } UUID(high, low) } @@ -449,8 +450,10 @@ impl Default for UUID { impl Serializable for UUID { fn read_from(buf: &mut R) -> Result { - Result::Ok(UUID(buf.read_u64::()?, - buf.read_u64::()?)) + Result::Ok(UUID( + buf.read_u64::()?, + buf.read_u64::()?, + )) } fn write_to(&self, buf: &mut W) -> Result<(), Error> { buf.write_u64::(self.0)?; @@ -496,8 +499,7 @@ impl Serializable for Biomes3D { } } - -pub trait Lengthable : Serializable + Copy + Default { +pub trait Lengthable: Serializable + Copy + Default { fn into_len(self) -> usize; fn from_len(_: usize) -> Self; } @@ -507,7 +509,7 @@ pub struct LenPrefixed { pub data: Vec, } -impl LenPrefixed { +impl LenPrefixed { pub fn new(data: Vec) -> LenPrefixed { LenPrefixed { len: Default::default(), @@ -516,7 +518,7 @@ impl LenPrefixed { } } -impl Serializable for LenPrefixed { +impl Serializable for LenPrefixed { fn read_from(buf: &mut R) -> Result, Error> { let len_data: L = Serializable::read_from(buf)?; let len: usize = len_data.into_len(); @@ -541,8 +543,7 @@ impl Serializable for LenPrefixed { } } - -impl Default for LenPrefixed { +impl Default for LenPrefixed { fn default() -> Self { LenPrefixed { len: default::Default::default(), @@ -551,7 +552,7 @@ impl Default for LenPrefixed { } } -impl fmt::Debug for LenPrefixed { +impl fmt::Debug for LenPrefixed { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.data.fmt(f) } @@ -563,7 +564,7 @@ pub struct LenPrefixedBytes { pub data: Vec, } -impl LenPrefixedBytes { +impl LenPrefixedBytes { pub fn new(data: Vec) -> LenPrefixedBytes { LenPrefixedBytes { len: Default::default(), @@ -572,7 +573,7 @@ impl LenPrefixedBytes { } } -impl Serializable for LenPrefixedBytes { +impl Serializable for LenPrefixedBytes { fn read_from(buf: &mut R) -> Result, Error> { let len_data: L = Serializable::read_from(buf)?; let len: usize = len_data.into_len(); @@ -592,8 +593,7 @@ impl Serializable for LenPrefixedBytes { } } - -impl Default for LenPrefixedBytes { +impl Default for LenPrefixedBytes { fn default() -> Self { LenPrefixedBytes { len: default::Default::default(), @@ -602,7 +602,7 @@ impl Default for LenPrefixedBytes { } } -impl fmt::Debug for LenPrefixedBytes { +impl fmt::Debug for LenPrefixedBytes { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.data.fmt(f) } @@ -610,7 +610,11 @@ impl fmt::Debug for LenPrefixedBytes { impl Lengthable for bool { fn into_len(self) -> usize { - if self { 1 } else { 0 } + if self { + 1 + } else { + 0 + } } fn from_len(u: usize) -> bool { @@ -618,7 +622,6 @@ impl Lengthable for bool { } } - impl Lengthable for u8 { fn into_len(self) -> usize { self as usize @@ -685,7 +688,12 @@ impl convert::From> for f64 { } } -impl fmt::Debug for FixedPoint5 where T: fmt::Display, f64: convert::From, T: NumCast + Copy { +impl fmt::Debug for FixedPoint5 +where + T: fmt::Display, + f64: convert::From, + T: NumCast + Copy, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let x: f64 = (*self).into(); write!(f, "FixedPoint5(#{} = {}f)", self.0, x) @@ -726,7 +734,12 @@ impl convert::From> for f64 { } } -impl fmt::Debug for FixedPoint12 where T: fmt::Display, f64: convert::From, T: NumCast + Copy { +impl fmt::Debug for FixedPoint12 +where + T: fmt::Display, + f64: convert::From, + T: NumCast + Copy, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { let x: f64 = (*self).into(); write!(f, "FixedPoint12(#{} = {}f)", self.0, x) @@ -751,7 +764,7 @@ impl Lengthable for VarInt { impl Serializable for VarInt { /// Decodes a `VarInt` from the Reader fn read_from(buf: &mut R) -> Result { - const PART : u32 = 0x7F; + const PART: u32 = 0x7F; let mut size = 0; let mut val = 0u32; loop { @@ -762,7 +775,7 @@ impl Serializable for VarInt { return Result::Err(Error::Err("VarInt too big".to_owned())); } if (b & 0x80) == 0 { - break + break; } } @@ -771,7 +784,7 @@ impl Serializable for VarInt { /// Encodes a `VarInt` into the Writer fn write_to(&self, buf: &mut W) -> Result<(), Error> { - const PART : u32 = 0x7F; + const PART: u32 = 0x7F; let mut val = self.0 as u32; loop { if (val & !PART) == 0 { @@ -826,7 +839,11 @@ impl Serializable for VarShort { } fn write_to(&self, buf: &mut W) -> Result<(), Error> { - assert!(self.0 >= 0 && self.0 <= 0x7fffff, "VarShort invalid value: {}", self.0); + assert!( + self.0 >= 0 && self.0 <= 0x7fffff, + "VarShort invalid value: {}", + self.0 + ); let mut low = self.0 & 0x7fff; let high = (self.0 & 0x7f8000) >> 15; if high != 0 { @@ -873,7 +890,7 @@ impl Lengthable for VarLong { impl Serializable for VarLong { /// Decodes a `VarLong` from the Reader fn read_from(buf: &mut R) -> Result { - const PART : u64 = 0x7F; + const PART: u64 = 0x7F; let mut size = 0; let mut val = 0u64; loop { @@ -884,7 +901,7 @@ impl Serializable for VarLong { return Result::Err(Error::Err("VarLong too big".to_owned())); } if (b & 0x80) == 0 { - break + break; } } @@ -893,7 +910,7 @@ impl Serializable for VarLong { /// Encodes a `VarLong` into the Writer fn write_to(&self, buf: &mut W) -> Result<(), Error> { - const PART : u64 = 0x7F; + const PART: u64 = 0x7F; let mut val = self.0 as u64; loop { if (val & !PART) == 0 { @@ -924,7 +941,7 @@ impl Serializable for Position { Ok(Position::new( ((pos as i64) >> 38) as i32, (((pos as i64) >> 26) & 0xFFF) as i32, - ((pos as i64) << 38 >> 38) as i32 + ((pos as i64) << 38 >> 38) as i32, )) } fn write_to(&self, buf: &mut W) -> Result<(), Error> { @@ -936,7 +953,6 @@ impl Serializable for Position { } } - /// Direction is used to define whether packets are going to the /// server or the client. #[derive(Clone, Copy, Debug)] @@ -1058,9 +1074,13 @@ impl Conn { let mut write = ZlibEncoder::new(io::Cursor::new(buf), Compression::default()); write.read_to_end(&mut new)?; if is_network_debug() { - debug!("Compressed for sending {} bytes to {} since > threshold {}, new={:?}", - uncompressed_size, new.len(), self.compression_threshold, - new); + debug!( + "Compressed for sending {} bytes to {} since > threshold {}, new={:?}", + uncompressed_size, + new.len(), + self.compression_threshold, + new + ); } buf = new; } @@ -1090,8 +1110,13 @@ impl Conn { reader.read_to_end(&mut new)?; } if is_network_debug() { - debug!("Decompressed threshold={} len={} uncompressed_size={} to {} bytes", - self.compression_threshold, len, uncompressed_size, new.len()); + debug!( + "Decompressed threshold={} len={} uncompressed_size={} to {} bytes", + self.compression_threshold, + len, + uncompressed_size, + new.len() + ); } buf = io::Cursor::new(new); } @@ -1104,7 +1129,10 @@ impl Conn { }; if is_network_debug() { - debug!("about to parse id={:x}, dir={:?} state={:?}", id, dir, self.state); + debug!( + "about to parse id={:x}, dir={:?} state={:?}", + id, dir, self.state + ); fs::File::create("last-packet")?.write_all(buf.get_ref())?; } @@ -1119,10 +1147,12 @@ impl Conn { let pos = buf.position() as usize; let ibuf = buf.into_inner(); if ibuf.len() != pos { - return Result::Err(Error::Err(format!("Failed to read all of packet 0x{:X}, \ + return Result::Err(Error::Err(format!( + "Failed to read all of packet 0x{:X}, \ had {} bytes left", - id, - ibuf.len() - pos))) + id, + ibuf.len() - pos + ))); } Result::Ok(val) } @@ -1140,10 +1170,10 @@ impl Conn { } pub fn do_status(mut self) -> Result<(Status, Duration), Error> { - use serde_json::Value; - use self::packet::status::serverbound::*; use self::packet::handshake::serverbound::Handshake; + use self::packet::status::serverbound::*; use self::packet::Packet; + use serde_json::Value; let host = self.host.clone(); let port = self.port; self.write_packet(Handshake { @@ -1191,16 +1221,22 @@ impl Conn { if let Value::Array(items) = modlist { for item in items { if let Value::Object(obj) = item { - let modid = obj.get("modid").unwrap().as_str().unwrap().to_string(); - let version = obj.get("version").unwrap().as_str().unwrap().to_string(); + let modid = + obj.get("modid").unwrap().as_str().unwrap().to_string(); + let version = + obj.get("version").unwrap().as_str().unwrap().to_string(); - forge_mods.push(crate::protocol::forge::ForgeMod { modid, version }); + forge_mods + .push(crate::protocol::forge::ForgeMod { modid, version }); } } } } } else { - panic!("Unrecognized modinfo type in server ping response: {} in {}", modinfo_type, modinfo); + panic!( + "Unrecognized modinfo type in server ping response: {} in {}", + modinfo_type, modinfo + ); } } } @@ -1211,7 +1247,8 @@ impl Conn { for item in items { if let Value::Object(obj) = item { let modid = obj.get("modId").unwrap().as_str().unwrap().to_string(); - let modmarker = obj.get("modmarker").unwrap().as_str().unwrap().to_string(); + let modmarker = + obj.get("modmarker").unwrap().as_str().unwrap().to_string(); let version = modmarker; @@ -1222,29 +1259,41 @@ impl Conn { } } - Ok((Status { - version: StatusVersion { - name: version.get("name").and_then(Value::as_str).ok_or(invalid_status())? - .to_owned(), - protocol: version.get("protocol") - .and_then(Value::as_i64) - .ok_or(invalid_status())? as i32, + Ok(( + Status { + version: StatusVersion { + name: version + .get("name") + .and_then(Value::as_str) + .ok_or(invalid_status())? + .to_owned(), + protocol: version + .get("protocol") + .and_then(Value::as_i64) + .ok_or(invalid_status())? as i32, + }, + players: StatusPlayers { + max: players + .get("max") + .and_then(Value::as_i64) + .ok_or(invalid_status())? as i32, + online: players + .get("online") + .and_then(Value::as_i64) + .ok_or(invalid_status())? as i32, + sample: Vec::new(), /* TODO */ + }, + description: format::Component::from_value( + val.get("description").ok_or(invalid_status())?, + ), + favicon: val + .get("favicon") + .and_then(Value::as_str) + .map(|v| v.to_owned()), + forge_mods, }, - players: StatusPlayers { - max: players.get("max") - .and_then(Value::as_i64) - .ok_or(invalid_status())? as i32, - online: players.get("online") - .and_then(Value::as_i64) - .ok_or(invalid_status())? as i32, - sample: Vec::new(), /* TODO */ - }, - description: format::Component::from_value(val.get("description") - .ok_or(invalid_status())?), - favicon: val.get("favicon").and_then(Value::as_str).map(|v| v.to_owned()), - forge_mods, - }, - ping)) + ping, + )) } } diff --git a/protocol/src/protocol/mojang.rs b/protocol/src/protocol/mojang.rs index 165fa38..b781ff4 100644 --- a/protocol/src/protocol/mojang.rs +++ b/protocol/src/protocol/mojang.rs @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use sha1::{self, Digest}; -use serde_json::json; #[cfg(not(target_arch = "wasm32"))] use reqwest; +use serde_json::json; +use sha1::{self, Digest}; #[derive(Clone, Debug)] pub struct Profile { @@ -33,17 +33,18 @@ const VALIDATE_URL: &str = "https://authserver.mojang.com/validate"; impl Profile { pub fn login(username: &str, password: &str, token: &str) -> Result { let req_msg = json!({ - "username": username, - "password": password, - "clientToken": token, - "agent": { - "name": "Minecraft", - "version": 1 - }}); + "username": username, + "password": password, + "clientToken": token, + "agent": { + "name": "Minecraft", + "version": 1 + }}); let req = serde_json::to_string(&req_msg)?; let client = reqwest::blocking::Client::new(); - let res = client.post(LOGIN_URL) + let res = client + .post(LOGIN_URL) .header(reqwest::header::CONTENT_TYPE, "application/json") .body(req) .send()?; @@ -53,33 +54,47 @@ impl Profile { return Err(super::Error::Err(format!( "{}: {}", error, - ret.get("errorMessage").and_then(|v| v.as_str()).unwrap()) - )); + ret.get("errorMessage").and_then(|v| v.as_str()).unwrap() + ))); } Ok(Profile { - username: ret.pointer("/selectedProfile/name").and_then(|v| v.as_str()).unwrap().to_owned(), - id: ret.pointer("/selectedProfile/id").and_then(|v| v.as_str()).unwrap().to_owned(), - access_token: ret.get("accessToken").and_then(|v| v.as_str()).unwrap().to_owned(), + username: ret + .pointer("/selectedProfile/name") + .and_then(|v| v.as_str()) + .unwrap() + .to_owned(), + id: ret + .pointer("/selectedProfile/id") + .and_then(|v| v.as_str()) + .unwrap() + .to_owned(), + access_token: ret + .get("accessToken") + .and_then(|v| v.as_str()) + .unwrap() + .to_owned(), }) } pub fn refresh(self, token: &str) -> Result { let req_msg = json!({ - "accessToken": self.access_token.clone(), - "clientToken": token - }); + "accessToken": self.access_token.clone(), + "clientToken": token + }); let req = serde_json::to_string(&req_msg)?; let client = reqwest::blocking::Client::new(); - let res = client.post(VALIDATE_URL) + let res = client + .post(VALIDATE_URL) .header(reqwest::header::CONTENT_TYPE, "application/json") .body(req) .send()?; if res.status() != reqwest::StatusCode::NO_CONTENT { let req = serde_json::to_string(&req_msg)?; // TODO: fix parsing twice to avoid move - // Refresh needed - let res = client.post(REFRESH_URL) + // Refresh needed + let res = client + .post(REFRESH_URL) .header(reqwest::header::CONTENT_TYPE, "application/json") .body(req) .send()?; @@ -89,19 +104,36 @@ impl Profile { return Err(super::Error::Err(format!( "{}: {}", error, - ret.get("errorMessage").and_then(|v| v.as_str()).unwrap()) - )); + ret.get("errorMessage").and_then(|v| v.as_str()).unwrap() + ))); } return Ok(Profile { - username: ret.pointer("/selectedProfile/name").and_then(|v| v.as_str()).unwrap().to_owned(), - id: ret.pointer("/selectedProfile/id").and_then(|v| v.as_str()).unwrap().to_owned(), - access_token: ret.get("accessToken").and_then(|v| v.as_str()).unwrap().to_owned(), + username: ret + .pointer("/selectedProfile/name") + .and_then(|v| v.as_str()) + .unwrap() + .to_owned(), + id: ret + .pointer("/selectedProfile/id") + .and_then(|v| v.as_str()) + .unwrap() + .to_owned(), + access_token: ret + .get("accessToken") + .and_then(|v| v.as_str()) + .unwrap() + .to_owned(), }); } Ok(self) } - pub fn join_server(&self, server_id: &str, shared_key: &[u8], public_key: &[u8]) -> Result<(), super::Error> { + pub fn join_server( + &self, + server_id: &str, + shared_key: &[u8], + public_key: &[u8], + ) -> Result<(), super::Error> { let mut hasher = sha1::Sha1::new(); hasher.input(server_id.as_bytes()); hasher.input(shared_key); @@ -114,7 +146,11 @@ impl Profile { if negative { twos_compliment(&mut hash); } - let hash_str = hash.iter().map(|b| format!("{:02x}", b)).collect::>().join(""); + let hash_str = hash + .iter() + .map(|b| format!("{:02x}", b)) + .collect::>() + .join(""); let hash_val = hash_str.trim_start_matches('0'); let hash_str = if negative { "-".to_owned() + &hash_val[..] @@ -130,7 +166,8 @@ impl Profile { let join = serde_json::to_string(&join_msg).unwrap(); let client = reqwest::blocking::Client::new(); - let res = client.post(JOIN_URL) + let res = client + .post(JOIN_URL) .header(reqwest::header::CONTENT_TYPE, "application/json") .body(join) .send()?; diff --git a/protocol/src/protocol/packet.rs b/protocol/src/protocol/packet.rs index a1acce9..edf490a 100644 --- a/protocol/src/protocol/packet.rs +++ b/protocol/src/protocol/packet.rs @@ -2193,7 +2193,8 @@ impl Serializable for Advancement { }; let criteria: LenPrefixed = Serializable::read_from(buf)?; - let requirements: LenPrefixed> = Serializable::read_from(buf)?; + let requirements: LenPrefixed> = + Serializable::read_from(buf)?; Ok(Advancement { id, parent_id, @@ -2210,7 +2211,6 @@ impl Serializable for Advancement { self.criteria.write_to(buf)?; self.requirements.write_to(buf) } - } #[derive(Debug, Default)] @@ -2264,7 +2264,6 @@ impl Serializable for AdvancementDisplay { self.x_coord.write_to(buf)?; self.y_coord.write_to(buf) } - } #[derive(Debug, Default)] @@ -2315,8 +2314,6 @@ impl Serializable for CriterionProgress { } } - - #[derive(Debug, Default)] pub struct EntityProperty { pub key: String, @@ -2363,7 +2360,6 @@ impl Serializable for EntityProperty_i16 { } } - #[derive(Debug, Default)] pub struct PropertyModifier { pub uuid: UUID, @@ -2434,33 +2430,25 @@ impl Serializable for PlayerInfoData { }; m.players.push(p); } - 1 => { - m.players.push(PlayerDetail::UpdateGamemode { - uuid, - gamemode: Serializable::read_from(buf)?, - }) - } - 2 => { - m.players.push(PlayerDetail::UpdateLatency { - uuid, - ping: Serializable::read_from(buf)?, - }) - } - 3 => { - m.players.push(PlayerDetail::UpdateDisplayName { - uuid, - display: { - if bool::read_from(buf)? { - Some(Serializable::read_from(buf)?) - } else { - None - } - }, - }) - } - 4 => { - m.players.push(PlayerDetail::Remove { uuid: uuid }) - } + 1 => m.players.push(PlayerDetail::UpdateGamemode { + uuid, + gamemode: Serializable::read_from(buf)?, + }), + 2 => m.players.push(PlayerDetail::UpdateLatency { + uuid, + ping: Serializable::read_from(buf)?, + }), + 3 => m.players.push(PlayerDetail::UpdateDisplayName { + uuid, + display: { + if bool::read_from(buf)? { + Some(Serializable::read_from(buf)?) + } else { + None + } + }, + }), + 4 => m.players.push(PlayerDetail::Remove { uuid: uuid }), _ => panic!(), } } @@ -2619,8 +2607,7 @@ impl Serializable for Recipe { } }; - let data = - match ty.as_ref() { + let data = match ty.as_ref() { "minecraft:crafting_shapeless" => RecipeData::Shapeless { group: Serializable::read_from(buf)?, ingredients: Serializable::read_from(buf)?, @@ -2634,12 +2621,18 @@ impl Serializable for Recipe { let capacity = width.0 as usize * height.0 as usize; let mut ingredients = Vec::with_capacity(capacity); - for _ in 0 .. capacity { + for _ in 0..capacity { ingredients.push(Serializable::read_from(buf)?); } let result: Option = Serializable::read_from(buf)?; - RecipeData::Shaped { width, height, group, ingredients, result } + RecipeData::Shaped { + width, + height, + group, + ingredients, + result, + } } "minecraft:crafting_special_armordye" => RecipeData::ArmorDye, "minecraft:crafting_special_bookcloning" => RecipeData::BookCloning, @@ -2688,7 +2681,7 @@ impl Serializable for Recipe { ingredient: Serializable::read_from(buf)?, result: Serializable::read_from(buf)?, }, - _ => panic!("unrecognized recipe type: {}", ty) + _ => panic!("unrecognized recipe type: {}", ty), }; Ok(Recipe { id, ty, data }) @@ -2748,7 +2741,11 @@ impl Serializable for Trade { xp: Serializable::read_from(buf)?, special_price: Serializable::read_from(buf)?, price_multiplier: Serializable::read_from(buf)?, - demand: if protocol_version >= 498 { Some(Serializable::read_from(buf)?) } else { None }, + demand: if protocol_version >= 498 { + Some(Serializable::read_from(buf)?) + } else { + None + }, }) } @@ -2757,7 +2754,6 @@ impl Serializable for Trade { } } - #[derive(Debug, Default)] pub struct CommandNode { pub flags: u8, @@ -2843,7 +2839,6 @@ pub enum CommandProperty { Dimension, } - impl Serializable for CommandNode { fn read_from(buf: &mut R) -> Result { let flags: u8 = Serializable::read_from(buf)?; @@ -2865,11 +2860,12 @@ impl Serializable for CommandNode { None }; - let name: Option = if node_type == CommandNodeType::Argument || node_type == CommandNodeType::Literal { - Serializable::read_from(buf)? - } else { - None - }; + let name: Option = + if node_type == CommandNodeType::Argument || node_type == CommandNodeType::Literal { + Serializable::read_from(buf)? + } else { + None + }; let parser: Option = if node_type == CommandNodeType::Argument { Serializable::read_from(buf)? } else { @@ -2881,27 +2877,51 @@ impl Serializable for CommandNode { "brigadier:bool" => CommandProperty::Bool, "brigadier:double" => { let flags = Serializable::read_from(buf)?; - let min = if flags & 0x01 != 0 { Some(Serializable::read_from(buf)?) } else { None }; - let max = if flags & 0x02 != 0 { Some(Serializable::read_from(buf)?) } else { None }; + let min = if flags & 0x01 != 0 { + Some(Serializable::read_from(buf)?) + } else { + None + }; + let max = if flags & 0x02 != 0 { + Some(Serializable::read_from(buf)?) + } else { + None + }; CommandProperty::Double { flags, min, max } - }, + } "brigadier:float" => { let flags = Serializable::read_from(buf)?; - let min = if flags & 0x01 != 0 { Some(Serializable::read_from(buf)?) } else { None }; - let max = if flags & 0x02 != 0 { Some(Serializable::read_from(buf)?) } else { None }; + let min = if flags & 0x01 != 0 { + Some(Serializable::read_from(buf)?) + } else { + None + }; + let max = if flags & 0x02 != 0 { + Some(Serializable::read_from(buf)?) + } else { + None + }; CommandProperty::Float { flags, min, max } - }, + } "brigadier:integer" => { let flags = Serializable::read_from(buf)?; - let min = if flags & 0x01 != 0 { Some(Serializable::read_from(buf)?) } else { None }; - let max = if flags & 0x02 != 0 { Some(Serializable::read_from(buf)?) } else { None }; + let min = if flags & 0x01 != 0 { + Some(Serializable::read_from(buf)?) + } else { + None + }; + let max = if flags & 0x02 != 0 { + Some(Serializable::read_from(buf)?) + } else { + None + }; CommandProperty::Integer { flags, min, max } + } + "brigadier:string" => CommandProperty::String { + token_type: Serializable::read_from(buf)?, }, - "brigadier:string" => { - CommandProperty::String { token_type: Serializable::read_from(buf)? } - }, - "minecraft:entity" => { - CommandProperty::Entity { flags: Serializable::read_from(buf)? } + "minecraft:entity" => CommandProperty::Entity { + flags: Serializable::read_from(buf)?, }, "minecraft:game_profile" => CommandProperty::GameProfile, "minecraft:block_pos" => CommandProperty::BlockPos, @@ -2926,8 +2946,8 @@ impl Serializable for CommandNode { "minecraft:particle" => CommandProperty::Particle, "minecraft:rotation" => CommandProperty::Rotation, "minecraft:scoreboard_slot" => CommandProperty::ScoreboardSlot, - "minecraft:score_holder" => { - CommandProperty::ScoreHolder { flags: Serializable::read_from(buf)? } + "minecraft:score_holder" => CommandProperty::ScoreHolder { + flags: Serializable::read_from(buf)?, }, "minecraft:swizzle" => CommandProperty::Swizzle, "minecraft:team" => CommandProperty::Team, @@ -2936,8 +2956,8 @@ impl Serializable for CommandNode { "minecraft:mob_effect" => CommandProperty::MobEffect, "minecraft:function" => CommandProperty::Function, "minecraft:entity_anchor" => CommandProperty::EntityAnchor, - "minecraft:range" => { - CommandProperty::Range { decimals: Serializable::read_from(buf)? } + "minecraft:range" => CommandProperty::Range { + decimals: Serializable::read_from(buf)?, }, "minecraft:int_range" => CommandProperty::IntRange, "minecraft:float_range" => CommandProperty::FloatRange, @@ -2956,12 +2976,18 @@ impl Serializable for CommandNode { None }; - Ok(CommandNode { flags, children, redirect_node, name, parser, properties, suggestions_type }) + Ok(CommandNode { + flags, + children, + redirect_node, + name, + parser, + properties, + suggestions_type, + }) } fn write_to(&self, _: &mut W) -> Result<(), Error> { unimplemented!() } } - - diff --git a/protocol/src/protocol/versions.rs b/protocol/src/protocol/versions.rs index 461bca1..0cad075 100644 --- a/protocol/src/protocol/versions.rs +++ b/protocol/src/protocol/versions.rs @@ -1,22 +1,22 @@ use super::*; -mod v1_15_1; -mod v1_14_4; -mod v1_14_3; -mod v1_14_2; -mod v1_14_1; -mod v1_14; -mod v19w02a; -mod v18w50a; -mod v1_13_2; -mod v1_12_2; -mod v1_11_2; -mod v1_10_2; -mod v1_9_2; -mod v1_9; mod v15w39c; -mod v1_8_9; +mod v18w50a; +mod v19w02a; +mod v1_10_2; +mod v1_11_2; +mod v1_12_2; +mod v1_13_2; +mod v1_14; +mod v1_14_1; +mod v1_14_2; +mod v1_14_3; +mod v1_14_4; +mod v1_15_1; mod v1_7_10; +mod v1_8_9; +mod v1_9; +mod v1_9_2; // https://wiki.vg/Protocol_History // https://wiki.vg/Protocol_version_numbers#Versions_after_the_Netty_rewrite @@ -52,7 +52,13 @@ pub fn protocol_name_to_protocol_version(s: String) -> i32 { } } -pub fn translate_internal_packet_id_for_version(version: i32, state: State, dir: Direction, id: i32, to_internal: bool) -> i32 { +pub fn translate_internal_packet_id_for_version( + version: i32, + state: State, + dir: Direction, + id: i32, + to_internal: bool, +) -> i32 { match version { 575 => v1_15_1::translate_internal_packet_id(state, dir, id, to_internal), 498 => v1_14_4::translate_internal_packet_id(state, dir, id, to_internal), diff --git a/protocol/src/protocol/versions/v15w39c.rs b/protocol/src/protocol/versions/v15w39c.rs index 9801571..f12dbda 100644 --- a/protocol/src/protocol/versions/v15w39c.rs +++ b/protocol/src/protocol/versions/v15w39c.rs @@ -137,5 +137,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v18w50a.rs b/protocol/src/protocol/versions/v18w50a.rs index 0a9d6a9..b153340 100644 --- a/protocol/src/protocol/versions/v18w50a.rs +++ b/protocol/src/protocol/versions/v18w50a.rs @@ -168,5 +168,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v19w02a.rs b/protocol/src/protocol/versions/v19w02a.rs index 9a2af5c..d24b82f 100644 --- a/protocol/src/protocol/versions/v19w02a.rs +++ b/protocol/src/protocol/versions/v19w02a.rs @@ -170,5 +170,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_10_2.rs b/protocol/src/protocol/versions/v1_10_2.rs index 02ddc6c..066006f 100644 --- a/protocol/src/protocol/versions/v1_10_2.rs +++ b/protocol/src/protocol/versions/v1_10_2.rs @@ -141,5 +141,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_11_2.rs b/protocol/src/protocol/versions/v1_11_2.rs index aa82c97..cf95ffe 100644 --- a/protocol/src/protocol/versions/v1_11_2.rs +++ b/protocol/src/protocol/versions/v1_11_2.rs @@ -141,5 +141,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_12_2.rs b/protocol/src/protocol/versions/v1_12_2.rs index 1e3b909..679b697 100644 --- a/protocol/src/protocol/versions/v1_12_2.rs +++ b/protocol/src/protocol/versions/v1_12_2.rs @@ -148,5 +148,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_13_2.rs b/protocol/src/protocol/versions/v1_13_2.rs index 04871b1..09f5aca 100644 --- a/protocol/src/protocol/versions/v1_13_2.rs +++ b/protocol/src/protocol/versions/v1_13_2.rs @@ -165,5 +165,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_14.rs b/protocol/src/protocol/versions/v1_14.rs index b5c9a9a..bd21510 100644 --- a/protocol/src/protocol/versions/v1_14.rs +++ b/protocol/src/protocol/versions/v1_14.rs @@ -175,5 +175,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_14_1.rs b/protocol/src/protocol/versions/v1_14_1.rs index b5c9a9a..bd21510 100644 --- a/protocol/src/protocol/versions/v1_14_1.rs +++ b/protocol/src/protocol/versions/v1_14_1.rs @@ -175,5 +175,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_14_2.rs b/protocol/src/protocol/versions/v1_14_2.rs index b5c9a9a..bd21510 100644 --- a/protocol/src/protocol/versions/v1_14_2.rs +++ b/protocol/src/protocol/versions/v1_14_2.rs @@ -175,5 +175,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_14_3.rs b/protocol/src/protocol/versions/v1_14_3.rs index a5eebf2..5b05fde 100644 --- a/protocol/src/protocol/versions/v1_14_3.rs +++ b/protocol/src/protocol/versions/v1_14_3.rs @@ -175,5 +175,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_14_4.rs b/protocol/src/protocol/versions/v1_14_4.rs index 60be91a..820c60f 100644 --- a/protocol/src/protocol/versions/v1_14_4.rs +++ b/protocol/src/protocol/versions/v1_14_4.rs @@ -176,5 +176,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_15_1.rs b/protocol/src/protocol/versions/v1_15_1.rs index 6c3386c..e5ae7dd 100644 --- a/protocol/src/protocol/versions/v1_15_1.rs +++ b/protocol/src/protocol/versions/v1_15_1.rs @@ -176,5 +176,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_7_10.rs b/protocol/src/protocol/versions/v1_7_10.rs index c930e42..8da2137 100644 --- a/protocol/src/protocol/versions/v1_7_10.rs +++ b/protocol/src/protocol/versions/v1_7_10.rs @@ -124,5 +124,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_8_9.rs b/protocol/src/protocol/versions/v1_8_9.rs index c645c45..8130a10 100644 --- a/protocol/src/protocol/versions/v1_8_9.rs +++ b/protocol/src/protocol/versions/v1_8_9.rs @@ -135,5 +135,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_9.rs b/protocol/src/protocol/versions/v1_9.rs index 7b714e8..dc817dc 100644 --- a/protocol/src/protocol/versions/v1_9.rs +++ b/protocol/src/protocol/versions/v1_9.rs @@ -142,5 +142,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/protocol/versions/v1_9_2.rs b/protocol/src/protocol/versions/v1_9_2.rs index ecd1e28..9ee61b3 100644 --- a/protocol/src/protocol/versions/v1_9_2.rs +++ b/protocol/src/protocol/versions/v1_9_2.rs @@ -142,5 +142,3 @@ protocol_packet_ids!( } } ); - - diff --git a/protocol/src/types/bit/map.rs b/protocol/src/types/bit/map.rs index 2f86979..66cfc98 100644 --- a/protocol/src/types/bit/map.rs +++ b/protocol/src/types/bit/map.rs @@ -61,7 +61,7 @@ impl Map { } pub fn from_raw(bits: Vec, size: usize) -> Map { Map { - length: (bits.len()*64 + (size-1)) / size, + length: (bits.len() * 64 + (size - 1)) / size, bit_size: size, bits, } diff --git a/protocol/src/types/bit/mod.rs b/protocol/src/types/bit/mod.rs index 6754eab..812da5d 100644 --- a/protocol/src/types/bit/mod.rs +++ b/protocol/src/types/bit/mod.rs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub mod set; pub mod map; +pub mod set; -pub use self::set::Set; pub use self::map::Map; +pub use self::set::Set; diff --git a/protocol/src/types/bit/set.rs b/protocol/src/types/bit/set.rs index 894d936..14cf4fc 100644 --- a/protocol/src/types/bit/set.rs +++ b/protocol/src/types/bit/set.rs @@ -34,7 +34,9 @@ fn test_set() { impl Set { pub fn new(size: usize) -> Set { - Set { data: vec![0; (size + 63) / 64] } + Set { + data: vec![0; (size + 63) / 64], + } } pub fn resize(&mut self, new_size: usize) { diff --git a/protocol/src/types/hash.rs b/protocol/src/types/hash.rs index cf16af9..a06519b 100644 --- a/protocol/src/types/hash.rs +++ b/protocol/src/types/hash.rs @@ -1,5 +1,3 @@ - - use std::hash::Hasher; pub struct FNVHash(u64); diff --git a/protocol/src/types/metadata.rs b/protocol/src/types/metadata.rs index 17c18eb..2297d5f 100644 --- a/protocol/src/types/metadata.rs +++ b/protocol/src/types/metadata.rs @@ -12,24 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::HashMap; -use std::marker::PhantomData; -use std::io; -use std::fmt; -use crate::protocol; -use crate::protocol::Serializable; -use crate::protocol::LenPrefixed; use crate::format; use crate::item; -use crate::shared::Position; use crate::nbt; +use crate::protocol; +use crate::protocol::LenPrefixed; +use crate::protocol::Serializable; +use crate::shared::Position; +use std::collections::HashMap; +use std::fmt; +use std::io; +use std::marker::PhantomData; pub struct MetadataKey { index: i32, ty: PhantomData, } -impl MetadataKey { +impl MetadataKey { #[allow(dead_code)] fn new(index: i32) -> MetadataKey { MetadataKey { @@ -45,7 +45,9 @@ pub struct Metadata { impl Metadata { pub fn new() -> Metadata { - Metadata { map: HashMap::new() } + Metadata { + map: HashMap::new(), + } } pub fn get(&self, key: &MetadataKey) -> Option<&T> { @@ -77,14 +79,22 @@ impl Metadata { 3 => m.put_raw(index, f32::read_from(buf)?), 4 => m.put_raw(index, String::read_from(buf)?), 5 => m.put_raw(index, Option::::read_from(buf)?), - 6 => m.put_raw(index, - [i32::read_from(buf)?, - i32::read_from(buf)?, - i32::read_from(buf)?]), - 7 => m.put_raw(index, - [f32::read_from(buf)?, - f32::read_from(buf)?, - f32::read_from(buf)?]), + 6 => m.put_raw( + index, + [ + i32::read_from(buf)?, + i32::read_from(buf)?, + i32::read_from(buf)?, + ], + ), + 7 => m.put_raw( + index, + [ + f32::read_from(buf)?, + f32::read_from(buf)?, + f32::read_from(buf)?, + ], + ), _ => return Err(protocol::Error::Err("unknown metadata type".to_owned())), } } @@ -100,8 +110,7 @@ impl Metadata { let ty_index: u8 = *k as u8; const TYPE_SHIFT: usize = 5; - match *v - { + match *v { Value::Byte(ref val) => { u8::write_to(&(ty_index | (0 << TYPE_SHIFT)), buf)?; val.write_to(buf)?; @@ -165,10 +174,14 @@ impl Metadata { 4 => m.put_raw(index, format::Component::read_from(buf)?), 5 => m.put_raw(index, Option::::read_from(buf)?), 6 => m.put_raw(index, bool::read_from(buf)?), - 7 => m.put_raw(index, - [f32::read_from(buf)?, - f32::read_from(buf)?, - f32::read_from(buf)?]), + 7 => m.put_raw( + index, + [ + f32::read_from(buf)?, + f32::read_from(buf)?, + f32::read_from(buf)?, + ], + ), 8 => m.put_raw(index, Position::read_from(buf)?), 9 => { if bool::read_from(buf)? { @@ -287,13 +300,20 @@ impl Metadata { 2 => m.put_raw(index, f32::read_from(buf)?), 3 => m.put_raw(index, String::read_from(buf)?), 4 => m.put_raw(index, format::Component::read_from(buf)?), - 5 => m.put_raw(index, LenPrefixed::::read_from(buf)?), + 5 => m.put_raw( + index, + LenPrefixed::::read_from(buf)?, + ), 6 => m.put_raw(index, Option::::read_from(buf)?), 7 => m.put_raw(index, bool::read_from(buf)?), - 8 => m.put_raw(index, - [f32::read_from(buf)?, - f32::read_from(buf)?, - f32::read_from(buf)?]), + 8 => m.put_raw( + index, + [ + f32::read_from(buf)?, + f32::read_from(buf)?, + f32::read_from(buf)?, + ], + ), 9 => m.put_raw(index, Position::read_from(buf)?), 10 => { if bool::read_from(buf)? { @@ -328,7 +348,7 @@ impl Metadata { } else { m.put_raw::>(index, None); } - }, + } 18 => m.put_raw(index, PoseData::read_from(buf)?), _ => return Err(protocol::Error::Err("unknown metadata type".to_owned())), } @@ -427,8 +447,6 @@ impl Metadata { u8::write_to(&0xFF, buf)?; Ok(()) } - - } impl Serializable for Metadata { @@ -571,7 +589,7 @@ impl Serializable for ParticleData { 1 => ParticleData::AngryVillager, 2 => ParticleData::Barrier, 3 => ParticleData::Block { - block_state: Serializable::read_from(buf)? + block_state: Serializable::read_from(buf)?, }, 4 => ParticleData::Bubble, 5 => ParticleData::Cloud, @@ -649,7 +667,11 @@ impl Serializable for VillagerData { let villager_type = protocol::VarInt::read_from(buf)?; let profession = protocol::VarInt::read_from(buf)?; let level = protocol::VarInt::read_from(buf)?; - Ok(VillagerData { villager_type, profession, level }) + Ok(VillagerData { + villager_type, + profession, + level, + }) } fn write_to(&self, _buf: &mut W) -> Result<(), protocol::Error> { @@ -688,8 +710,6 @@ impl Serializable for PoseData { } } - - pub trait MetaValue { fn unwrap(_: &Value) -> &Self; fn wrap(self) -> Value; @@ -779,7 +799,6 @@ impl MetaValue for LenPrefixed { } } - impl MetaValue for Option { fn unwrap(value: &Value) -> &Self { match *value { @@ -936,14 +955,12 @@ impl MetaValue for PoseData { } } - #[cfg(test)] mod test { use super::*; use std::marker::PhantomData; - const TEST: MetadataKey = - MetadataKey { + const TEST: MetadataKey = MetadataKey { index: 0, ty: PhantomData, }; diff --git a/protocol/src/types/mod.rs b/protocol/src/types/mod.rs index 5232c8c..dcde267 100644 --- a/protocol/src/types/mod.rs +++ b/protocol/src/types/mod.rs @@ -16,8 +16,8 @@ mod metadata; pub use self::metadata::*; pub mod bit; -pub mod nibble; pub mod hash; +pub mod nibble; #[derive(Clone, Copy, Debug)] pub enum Gamemode { diff --git a/protocol/src/types/nibble.rs b/protocol/src/types/nibble.rs index 91ecdc8..c1d6e79 100644 --- a/protocol/src/types/nibble.rs +++ b/protocol/src/types/nibble.rs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. - pub struct Array { pub data: Vec, } @@ -25,8 +24,8 @@ impl Array { } pub fn get(&self, idx: usize) -> u8 { - let val = self.data[idx>>1]; - if idx&1 == 0 { + let val = self.data[idx >> 1]; + if idx & 1 == 0 { val & 0xF } else { val >> 4 @@ -36,7 +35,7 @@ impl Array { pub fn set(&mut self, idx: usize, val: u8) { let i = idx >> 1; let old = self.data[i]; - if idx&1 == 0 { + if idx & 1 == 0 { self.data[i] = (old & 0xF0) | (val & 0xF); } else { self.data[i] = (old & 0x0F) | ((val & 0xF) << 4); diff --git a/resources/build.rs b/resources/build.rs index 600741d..12220ab 100644 --- a/resources/build.rs +++ b/resources/build.rs @@ -1,8 +1,8 @@ use std::env; use std::fs; -use std::path::{Path, PathBuf}; use std::io::BufWriter; use std::io::Write; +use std::path::{Path, PathBuf}; fn main() { let out_dir = env::var("OUT_DIR").unwrap(); @@ -13,7 +13,11 @@ fn main() { build_map(&mut out, &base); let mut file = BufWriter::new(fs::File::create(&dest.join("resources.rs")).unwrap()); - write!(file, "pub fn get_file(name: &str) -> Option<&'static [u8]> {{\n").unwrap(); + write!( + file, + "pub fn get_file(name: &str) -> Option<&'static [u8]> {{\n" + ) + .unwrap(); write!(file, " match name {{\n").unwrap(); for path in &out { let mut absolute_path = std::env::current_dir().unwrap(); @@ -22,10 +26,14 @@ fn main() { let absolute = absolute_path.to_str().unwrap().replace("\\", "/"); let relative = path.to_str().unwrap().replace("\\", "/"); - write!(file, " {:?} => Some(include_bytes!(\"{}\")),\n", relative, absolute).unwrap(); + write!( + file, + " {:?} => Some(include_bytes!(\"{}\")),\n", + relative, absolute + ) + .unwrap(); } write!(file, " _ => None\n }}\n}}\n").unwrap(); - } fn build_map(out: &mut Vec, path: &Path) { diff --git a/resources/src/lib.rs b/resources/src/lib.rs index 6b4e399..9b885ff 100644 --- a/resources/src/lib.rs +++ b/resources/src/lib.rs @@ -1,2 +1 @@ - include!(concat!(env!("OUT_DIR"), "/resources.rs")); diff --git a/shared/src/axis.rs b/shared/src/axis.rs index e0cfa6d..d255f63 100644 --- a/shared/src/axis.rs +++ b/shared/src/axis.rs @@ -1,10 +1,9 @@ - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum Axis { Y, Z, X, - None + None, } impl Axis { diff --git a/shared/src/direction.rs b/shared/src/direction.rs index 273dc98..d2c6938 100644 --- a/shared/src/direction.rs +++ b/shared/src/direction.rs @@ -1,4 +1,3 @@ - use crate::axis::Axis; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -15,9 +14,12 @@ pub enum Direction { impl Direction { pub fn all() -> Vec { vec![ - Direction::Down, Direction::Up, - Direction::North, Direction::South, - Direction::West, Direction::East, + Direction::Down, + Direction::Up, + Direction::North, + Direction::South, + Direction::West, + Direction::East, ] } @@ -117,7 +119,6 @@ impl Direction { } } - pub fn horizontal_index(&self) -> usize { match *self { Direction::North => 2, diff --git a/shared/src/lib.rs b/shared/src/lib.rs index a1b09fe..041be19 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -1,4 +1,3 @@ - pub mod axis; pub use self::axis::Axis; diff --git a/shared/src/position.rs b/shared/src/position.rs index c2ad4f1..b6dbe49 100644 --- a/shared/src/position.rs +++ b/shared/src/position.rs @@ -1,6 +1,5 @@ - -use std::fmt; use crate::direction::Direction; +use std::fmt; use std::ops; #[derive(Clone, Copy, PartialEq, Eq, Hash)] @@ -12,11 +11,7 @@ pub struct Position { impl Position { pub fn new(x: i32, y: i32, z: i32) -> Position { - Position { - x, - y, - z, - } + Position { x, y, z } } pub fn shift(self, dir: Direction) -> Position { diff --git a/src/chunk_builder.rs b/src/chunk_builder.rs index b0157c8..20b5b55 100644 --- a/src/chunk_builder.rs +++ b/src/chunk_builder.rs @@ -1,16 +1,15 @@ - -use std::thread; -use std::sync::mpsc; -use std::sync::{Arc, RwLock}; -use crate::world; -use crate::world::block; +use crate::model; use crate::render; use crate::resources; -use crate::model; -use crate::types::bit::Set; use crate::shared::Direction; -use rand::{self, SeedableRng, Rng}; +use crate::types::bit::Set; +use crate::world; +use crate::world::block; +use rand::{self, Rng, SeedableRng}; use rand_pcg; +use std::sync::mpsc; +use std::sync::{Arc, RwLock}; +use std::thread; const NUM_WORKERS: usize = 8; @@ -24,18 +23,27 @@ pub struct ChunkBuilder { } impl ChunkBuilder { - pub fn new(resources: Arc>, textures: Arc>) -> ChunkBuilder { - let models = Arc::new(RwLock::new(model::Factory::new(resources.clone(), textures))); + pub fn new( + resources: Arc>, + textures: Arc>, + ) -> ChunkBuilder { + let models = Arc::new(RwLock::new(model::Factory::new( + resources.clone(), + textures, + ))); let mut threads = vec![]; let mut free = vec![]; let (built_send, built_recv) = mpsc::channel(); - for i in 0 .. NUM_WORKERS { + for i in 0..NUM_WORKERS { let built_send = built_send.clone(); let (work_send, work_recv) = mpsc::channel(); let models = models.clone(); let id = i; - threads.push((work_send, thread::spawn(move || build_func(id, models, work_recv, built_send)))); + threads.push(( + work_send, + thread::spawn(move || build_func(id, models, work_recv, built_send)), + )); free.push((i, vec![], vec![])); } ChunkBuilder { @@ -47,7 +55,12 @@ impl ChunkBuilder { } } - pub fn tick(&mut self, world: &mut world::World, renderer: &mut render::Renderer, version: usize) { + pub fn tick( + &mut self, + world: &mut world::World, + renderer: &mut render::Renderer, + version: usize, + ) { { if version != self.resource_version { self.resource_version = version; @@ -58,35 +71,50 @@ impl ChunkBuilder { while let Ok((id, mut val)) = self.built_recv.try_recv() { world.reset_building_flag(val.position); - if let Some(sec) = world.get_section_mut(val.position.0, val.position.1, val.position.2) { + if let Some(sec) = world.get_section_mut(val.position.0, val.position.1, val.position.2) + { sec.cull_info = val.cull_info; - renderer.update_chunk_solid(&mut sec.render_buffer, &val.solid_buffer, val.solid_count); - renderer.update_chunk_trans(&mut sec.render_buffer, &val.trans_buffer, val.trans_count); + renderer.update_chunk_solid( + &mut sec.render_buffer, + &val.solid_buffer, + val.solid_count, + ); + renderer.update_chunk_trans( + &mut sec.render_buffer, + &val.trans_buffer, + val.trans_count, + ); } val.solid_buffer.clear(); val.trans_buffer.clear(); - self.free_builders.push((id, val.solid_buffer, val.trans_buffer)); + self.free_builders + .push((id, val.solid_buffer, val.trans_buffer)); } if self.free_builders.is_empty() { return; } - let dirty_sections = world.get_render_list().iter() - .map(|v| v.0) - .filter(|v| world.is_section_dirty(*v)) - .collect::>(); - for (x,y, z) in dirty_sections { + let dirty_sections = world + .get_render_list() + .iter() + .map(|v| v.0) + .filter(|v| world.is_section_dirty(*v)) + .collect::>(); + for (x, y, z) in dirty_sections { let t_id = self.free_builders.pop().unwrap(); world.set_building_flag((x, y, z)); let (cx, cy, cz) = (x << 4, y << 4, z << 4); let mut snapshot = world.capture_snapshot(cx - 2, cy - 2, cz - 2, 20, 20, 20); snapshot.make_relative(-2, -2, -2); - self.threads[t_id.0].0.send(BuildReq { - snapshot, - position: (x, y, z), - solid_buffer: t_id.1, - trans_buffer: t_id.2, - }).unwrap(); + self.threads[t_id.0] + .0 + .send(BuildReq { + snapshot, + position: (x, y, z), + solid_buffer: t_id.1, + trans_buffer: t_id.2, + }) + .unwrap(); if self.free_builders.is_empty() { return; } @@ -110,7 +138,12 @@ struct BuildReply { cull_info: CullInfo, } -fn build_func(id: usize, models: Arc>, work_recv: mpsc::Receiver, built_send: mpsc::Sender<(usize, BuildReply)>) { +fn build_func( + id: usize, + models: Arc>, + work_recv: mpsc::Receiver, + built_send: mpsc::Sender<(usize, BuildReply)>, +) { loop { let BuildReq { snapshot, @@ -127,17 +160,14 @@ fn build_func(id: usize, models: Arc>, work_recv: mpsc::R (((position.0 as u32) >> 8) & 0xff) as u8, (((position.0 as u32) >> 16) & 0xff) as u8, ((position.0 as u32) >> 24) as u8, - ((position.1 as u32) & 0xff) as u8, (((position.1 as u32) >> 8) & 0xff) as u8, (((position.1 as u32) >> 16) & 0xff) as u8, ((position.1 as u32) >> 24) as u8, - ((position.2 as u32) & 0xff) as u8, (((position.2 as u32) >> 8) & 0xff) as u8, (((position.2 as u32) >> 16) & 0xff) as u8, ((position.2 as u32) >> 24) as u8, - (((position.0 as u32 ^ position.2 as u32) | 1) & 0xff) as u8, ((((position.0 as u32 ^ position.2 as u32) | 1) >> 8) & 0xff) as u8, ((((position.0 as u32 ^ position.2 as u32) | 1) >> 16) & 0xff) as u8, @@ -147,9 +177,9 @@ fn build_func(id: usize, models: Arc>, work_recv: mpsc::R let mut solid_count = 0; let mut trans_count = 0; - for y in 0 .. 16 { - for x in 0 .. 16 { - for z in 0 .. 16 { + for y in 0..16 { + for x in 0..16 { + for z in 0..16 { let block = snapshot.get_block(x, y, z); let mat = block.get_material(); if !mat.renderable { @@ -161,26 +191,56 @@ fn build_func(id: usize, models: Arc>, work_recv: mpsc::R } match block { - block::Block::Water{..} | block::Block::FlowingWater{..} => { + block::Block::Water { .. } | block::Block::FlowingWater { .. } => { let tex = models.read().unwrap().textures.clone(); - trans_count += model::liquid::render_liquid(tex, false, &snapshot, x, y, z, &mut trans_buffer); + trans_count += model::liquid::render_liquid( + tex, + false, + &snapshot, + x, + y, + z, + &mut trans_buffer, + ); continue; - }, - block::Block::Lava{..} | block::Block::FlowingLava{..} => { + } + block::Block::Lava { .. } | block::Block::FlowingLava { .. } => { let tex = models.read().unwrap().textures.clone(); - solid_count += model::liquid::render_liquid(tex, true, &snapshot, x, y, z, &mut solid_buffer); + solid_count += model::liquid::render_liquid( + tex, + true, + &snapshot, + x, + y, + z, + &mut solid_buffer, + ); continue; - }, - _ => {}, + } + _ => {} } if mat.transparent { trans_count += model::Factory::get_state_model( - &models, block, &mut rng, &snapshot, x, y, z, &mut trans_buffer + &models, + block, + &mut rng, + &snapshot, + x, + y, + z, + &mut trans_buffer, ); } else { solid_count += model::Factory::get_state_model( - &models, block, &mut rng, &snapshot, x, y, z, &mut solid_buffer + &models, + block, + &mut rng, + &snapshot, + x, + y, + z, + &mut solid_buffer, ); } } @@ -189,14 +249,19 @@ fn build_func(id: usize, models: Arc>, work_recv: mpsc::R let cull_info = build_cull_info(&snapshot); - built_send.send((id, BuildReply { - position, - solid_buffer, - solid_count, - trans_buffer, - trans_count, - cull_info, - })).unwrap(); + built_send + .send(( + id, + BuildReply { + position, + solid_buffer, + solid_count, + trans_buffer, + trans_count, + cull_info, + }, + )) + .unwrap(); } } @@ -204,9 +269,9 @@ fn build_cull_info(snapshot: &world::Snapshot) -> CullInfo { let mut visited = Set::new(16 * 16 * 16); let mut info = CullInfo::new(); - for y in 0 .. 16 { - for z in 0 .. 16 { - for x in 0 .. 16 { + for y in 0..16 { + for z in 0..16 { + for x in 0..16 { if visited.get(x | (z << 4) | (y << 8)) { continue; } @@ -246,7 +311,11 @@ fn flood_fill(snapshot: &world::Snapshot, visited: &mut Set, x: i32, y: i32, z: } visited.set(idx, true); - if snapshot.get_block(x, y, z).get_material().should_cull_against { + if snapshot + .get_block(x, y, z) + .get_material() + .should_cull_against + { continue; } @@ -268,7 +337,7 @@ fn flood_fill(snapshot: &world::Snapshot, visited: &mut Set, x: i32, y: i32, z: for d in Direction::all() { let (ox, oy, oz) = d.get_offset(); - next_position.push_back((x+ox, y+oy, z+oz)); + next_position.push_back((x + ox, y + oy, z + oz)); } } touched @@ -278,7 +347,9 @@ fn flood_fill(snapshot: &world::Snapshot, visited: &mut Set, x: i32, y: i32, z: pub struct CullInfo(u64); impl CullInfo { - pub fn new() -> CullInfo { Default::default() } + pub fn new() -> CullInfo { + Default::default() + } pub fn all_vis() -> CullInfo { CullInfo(0xFFFFFFFFFFFFFFFF) diff --git a/src/console/mod.rs b/src/console/mod.rs index 1fcc3eb..0f21b6f 100644 --- a/src/console/mod.rs +++ b/src/console/mod.rs @@ -12,18 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::marker::PhantomData; -use std::collections::HashMap; +use log; use std::any::Any; -use std::cell::{RefCell, Ref}; +use std::cell::{Ref, RefCell}; +use std::collections::HashMap; +use std::io::{BufRead, BufReader, BufWriter, Write}; +use std::marker::PhantomData; use std::sync::{Arc, Mutex}; use std_or_web::fs; -use std::io::{BufWriter, Write, BufRead, BufReader}; -use log; -use crate::ui; +use crate::format::{Color, Component, TextComponent}; use crate::render; -use crate::format::{Component, TextComponent, Color}; +use crate::ui; #[cfg(target_arch = "wasm32")] use web_sys; @@ -126,21 +126,26 @@ pub struct Vars { } impl Vars { - pub fn new() -> Vars { Default::default() } + pub fn new() -> Vars { + Default::default() + } pub fn register(&mut self, var: CVar) - where CVar: Var + where + CVar: Var, { if self.vars.contains_key(var.name) { panic!("Key registered twice {}", var.name); } self.names.insert(var.name.to_owned(), var.name); - self.var_values.insert(var.name, RefCell::new(Box::new((var.default)()))); + self.var_values + .insert(var.name, RefCell::new(Box::new((var.default)()))); self.vars.insert(var.name, Box::new(var)); } pub fn get(&self, var: CVar) -> Ref - where CVar: Var + where + CVar: Var, { // Should never fail let var = self.var_values.get(var.name).unwrap().borrow(); @@ -148,7 +153,8 @@ impl Vars { } pub fn set(&self, var: CVar, val: T) - where CVar: Var + where + CVar: Var, { *self.var_values.get(var.name).unwrap().borrow_mut() = Box::new(val); self.save_config(); @@ -162,7 +168,10 @@ impl Vars { if line.starts_with('#') || line.is_empty() { continue; } - let parts = line.splitn(2, ' ').map(|v| v.to_owned()).collect::>(); + let parts = line + .splitn(2, ' ') + .map(|v| v.to_owned()) + .collect::>(); let (name, arg) = (&parts[0], &parts[1]); if let Some(var_name) = self.names.get(name) { let var = self.vars.get(var_name).unwrap(); @@ -184,11 +193,13 @@ impl Vars { for line in var.description().lines() { write!(file, "# {}\n", line).unwrap(); } - write!(file, - "{} {}\n\n", - name, - var.serialize(&self.var_values.get(name).unwrap().borrow())) - .unwrap(); + write!( + file, + "{} {}\n\n", + name, + var.serialize(&self.var_values.get(name).unwrap().borrow()) + ) + .unwrap(); } } } @@ -227,11 +238,13 @@ impl Console { self.active = !self.active; } - pub fn tick(&mut self, - ui_container: &mut ui::Container, - renderer: &render::Renderer, - delta: f64, - width: f64) { + pub fn tick( + &mut self, + ui_container: &mut ui::Container, + renderer: &render::Renderer, + delta: f64, + width: f64, + ) { if !self.active && self.position <= -220.0 { self.elements = None; return; @@ -281,12 +294,14 @@ impl Console { break; } let (_, height) = ui::Formatted::compute_size(renderer, line, w - 10.0); - elements.lines.push(ui::FormattedBuilder::new() - .text(line.clone()) - .position(5.0, 5.0 + offset) - .max_width(w - 10.0) - .alignment(ui::VAttach::Bottom, ui::HAttach::Left) - .create(&mut *background)); + elements.lines.push( + ui::FormattedBuilder::new() + .text(line.clone()) + .position(5.0, 5.0 + offset) + .max_width(w - 10.0) + .alignment(ui::VAttach::Bottom, ui::HAttach::Left) + .create(&mut *background), + ); offset += height; } } @@ -304,11 +319,16 @@ impl Console { file = &file[pos + 4..]; } - println_level(record.level(), format!("[{}:{}][{}] {}", - file, - record.line().unwrap_or(0), - record.level(), - record.args())); + println_level( + record.level(), + format!( + "[{}:{}][{}] {}", + file, + record.line().unwrap_or(0), + record.level(), + record.args() + ), + ); self.history.remove(0); let mut msg = TextComponent::new(""); msg.modifier.extra = Some(vec![ @@ -338,7 +358,7 @@ impl Console { Component::Text(msg) }, Component::Text(TextComponent::new("] ")), - Component::Text(TextComponent::new(&format!("{}", record.args()))) + Component::Text(TextComponent::new(&format!("{}", record.args()))), ]); self.history.push(Component::Text(msg)); self.dirty = true; @@ -366,8 +386,7 @@ impl log::Log for ConsoleProxy { } } - fn flush(&self) { - } + fn flush(&self) {} } unsafe impl Send for ConsoleProxy {} diff --git a/src/ecs/mod.rs b/src/ecs/mod.rs index 2fa3fd5..719bf8d 100644 --- a/src/ecs/mod.rs +++ b/src/ecs/mod.rs @@ -13,17 +13,17 @@ // limitations under the License. use crate::types::bit::Set as BSet; -use std::collections::{HashMap, HashSet}; -use std::hash::BuildHasherDefault; use crate::types::hash::FNVHash; use std::any::{Any, TypeId}; use std::cell::RefCell; +use std::collections::{HashMap, HashSet}; +use std::hash::BuildHasherDefault; use std::marker::PhantomData; use std::mem; use std::ptr; -use crate::world; use crate::render; +use crate::world; /// Used to reference an entity. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -38,7 +38,7 @@ pub struct Key { id: usize, _t: PhantomData, } -impl Clone for Key { +impl Clone for Key { fn clone(&self) -> Self { Key { id: self.id, @@ -46,7 +46,7 @@ impl Clone for Key { } } } -impl Copy for Key {} +impl Copy for Key {} /// Used to search for entities with the requested components. pub struct Filter { @@ -56,9 +56,7 @@ pub struct Filter { impl Filter { /// Creates an empty filter which matches everything pub fn new() -> Filter { - Filter { - bits: BSet::new(0), - } + Filter { bits: BSet::new(0) } } /// Adds the component to the filter. @@ -74,12 +72,29 @@ impl Filter { /// A system processes entities pub trait System { fn filter(&self) -> &Filter; - fn update(&mut self, m: &mut Manager, world: &mut world::World, renderer: &mut render::Renderer); + fn update( + &mut self, + m: &mut Manager, + world: &mut world::World, + renderer: &mut render::Renderer, + ); - fn entity_added(&mut self, _m: &mut Manager, _e: Entity, _world: &mut world::World, _renderer: &mut render::Renderer) { + fn entity_added( + &mut self, + _m: &mut Manager, + _e: Entity, + _world: &mut world::World, + _renderer: &mut render::Renderer, + ) { } - fn entity_removed(&mut self, _m: &mut Manager, _e: Entity, _world: &mut world::World, _renderer: &mut render::Renderer) { + fn entity_removed( + &mut self, + _m: &mut Manager, + _e: Entity, + _world: &mut world::World, + _renderer: &mut render::Renderer, + ) { } } @@ -110,11 +125,14 @@ impl Manager { pub fn new() -> Manager { Manager { num_components: 0, - entities: vec![(Some(EntityState { - last_components: BSet::new(0), - components: BSet::new(0), - removed: false, - }), 0)], // Has the world entity pre-defined + entities: vec![( + Some(EntityState { + last_components: BSet::new(0), + components: BSet::new(0), + removed: false, + }), + 0, + )], // Has the world entity pre-defined free_entities: vec![], components: vec![], @@ -166,7 +184,11 @@ impl Manager { self.process_entity_changes(world, renderer); } - fn process_entity_changes(&mut self, world: &mut world::World, renderer: &mut render::Renderer) { + fn process_entity_changes( + &mut self, + world: &mut world::World, + renderer: &mut render::Renderer, + ) { let changes = self.changed_entity_components.clone(); self.changed_entity_components = HashSet::with_hasher(BuildHasherDefault::default()); for entity in changes { @@ -177,11 +199,35 @@ impl Manager { state.components.or(&state.last_components); (cur, orig) }; - self.trigger_add_for_systems(entity, &state.last_components, &state.components, world, renderer); - self.trigger_add_for_render_systems(entity, &state.last_components, &state.components, world, renderer); - self.trigger_remove_for_systems(entity, &state.last_components, &state.components, world, renderer); - self.trigger_remove_for_render_systems(entity, &state.last_components, &state.components, world, renderer); - for i in 0 .. self.components.len() { + self.trigger_add_for_systems( + entity, + &state.last_components, + &state.components, + world, + renderer, + ); + self.trigger_add_for_render_systems( + entity, + &state.last_components, + &state.components, + world, + renderer, + ); + self.trigger_remove_for_systems( + entity, + &state.last_components, + &state.components, + world, + renderer, + ); + self.trigger_remove_for_render_systems( + entity, + &state.last_components, + &state.components, + world, + renderer, + ); + for i in 0..self.components.len() { if !state.components.get(i) && state.last_components.get(i) { let components = self.components.get_mut(i).and_then(|v| v.as_mut()).unwrap(); components.remove(entity.id); @@ -230,7 +276,7 @@ impl Manager { return Entity { id, generation: entity.1, - } + }; } let id = self.entities.len(); self.entities.push(( @@ -239,12 +285,9 @@ impl Manager { components: BSet::new(self.num_components), removed: false, }), - 0 + 0, )); - Entity { - id, - generation: 0, - } + Entity { id, generation: 0 } } /// Deallocates an entity and frees its components @@ -257,12 +300,16 @@ impl Manager { } /// Deallocates all entities/components excluding the world entity - pub fn remove_all_entities(&mut self, world: &mut world::World, renderer: &mut render::Renderer) { + pub fn remove_all_entities( + &mut self, + world: &mut world::World, + renderer: &mut render::Renderer, + ) { for (id, e) in self.entities[1..].iter_mut().enumerate() { if let Some(set) = e.0.as_mut() { set.components = BSet::new(self.components.len()); set.removed = true; - self.changed_entity_components.insert(Entity{ + self.changed_entity_components.insert(Entity { id: id + 1, generation: e.1, }); @@ -312,7 +359,13 @@ impl Manager { } let mut e = self.entities.get_mut(entity.id); let set = match e { - Some(ref mut val) => if val.1 == entity.generation { &mut val.0 } else { panic!("Missing entity") }, + Some(ref mut val) => { + if val.1 == entity.generation { + &mut val.0 + } else { + panic!("Missing entity") + } + } None => panic!("Missing entity"), }; let set = match set.as_mut() { @@ -327,24 +380,44 @@ impl Manager { } set.components.set(key.id, true); self.changed_entity_components.insert(entity); - let components = self.components.get_mut(key.id).and_then(|v| v.as_mut()).unwrap(); + let components = self + .components + .get_mut(key.id) + .and_then(|v| v.as_mut()) + .unwrap(); components.add(entity.id, val); } - fn trigger_add_for_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer) { + fn trigger_add_for_systems( + &mut self, + e: Entity, + old_set: &BSet, + new_set: &BSet, + world: &mut world::World, + renderer: &mut render::Renderer, + ) { let mut systems = self.systems.take().unwrap(); for sys in &mut systems { - if new_set.includes_set(&sys.filter().bits) && !old_set.includes_set(&sys.filter().bits) { + if new_set.includes_set(&sys.filter().bits) && !old_set.includes_set(&sys.filter().bits) + { sys.entity_added(self, e, world, renderer); } } self.systems = Some(systems); } - fn trigger_add_for_render_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer) { + fn trigger_add_for_render_systems( + &mut self, + e: Entity, + old_set: &BSet, + new_set: &BSet, + world: &mut world::World, + renderer: &mut render::Renderer, + ) { let mut systems = self.render_systems.take().unwrap(); for sys in &mut systems { - if new_set.includes_set(&sys.filter().bits) && !old_set.includes_set(&sys.filter().bits) { + if new_set.includes_set(&sys.filter().bits) && !old_set.includes_set(&sys.filter().bits) + { sys.entity_added(self, e, world, renderer); } } @@ -371,7 +444,13 @@ impl Manager { } let mut e = self.entities.get_mut(entity.id); let set = match e { - Some(ref mut val) => if val.1 == entity.generation { &mut val.0 } else { panic!("Missing entity") }, + Some(ref mut val) => { + if val.1 == entity.generation { + &mut val.0 + } else { + panic!("Missing entity") + } + } None => panic!("Missing entity"), }; let set = match set.as_mut() { @@ -382,7 +461,7 @@ impl Manager { panic!("Double change within a single tick"); } if !set.components.get(key.id) { - return false + return false; } set.components.set(key.id, false); self.changed_entity_components.insert(entity); @@ -390,20 +469,36 @@ impl Manager { true } - fn trigger_remove_for_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer) { + fn trigger_remove_for_systems( + &mut self, + e: Entity, + old_set: &BSet, + new_set: &BSet, + world: &mut world::World, + renderer: &mut render::Renderer, + ) { let mut systems = self.systems.take().unwrap(); for sys in &mut systems { - if !new_set.includes_set(&sys.filter().bits) && old_set.includes_set(&sys.filter().bits) { + if !new_set.includes_set(&sys.filter().bits) && old_set.includes_set(&sys.filter().bits) + { sys.entity_removed(self, e, world, renderer); } } self.systems = Some(systems); } - fn trigger_remove_for_render_systems(&mut self, e: Entity, old_set: &BSet, new_set: &BSet, world: &mut world::World, renderer: &mut render::Renderer) { + fn trigger_remove_for_render_systems( + &mut self, + e: Entity, + old_set: &BSet, + new_set: &BSet, + world: &mut world::World, + renderer: &mut render::Renderer, + ) { let mut systems = self.render_systems.take().unwrap(); for sys in &mut systems { - if !new_set.includes_set(&sys.filter().bits) && old_set.includes_set(&sys.filter().bits) { + if !new_set.includes_set(&sys.filter().bits) && old_set.includes_set(&sys.filter().bits) + { sys.entity_removed(self, e, world, renderer); } } @@ -424,7 +519,13 @@ impl Manager { None => return None, }; let set = match self.entities.get(entity.id).as_ref() { - Some(val) => if val.1 == entity.generation { &val.0 } else { return None }, + Some(val) => { + if val.1 == entity.generation { + &val.0 + } else { + return None; + } + } None => return None, }; if !set.as_ref().map_or(false, |v| v.components.get(key.id)) { @@ -442,13 +543,23 @@ impl Manager { } /// Returns the given component that the key points to if it exists. - pub fn get_component_mut<'a, 'b: 'a, T>(&'a mut self, entity: Entity, key: Key) -> Option<&'b mut T> { + pub fn get_component_mut<'a, 'b: 'a, T>( + &'a mut self, + entity: Entity, + key: Key, + ) -> Option<&'b mut T> { let components = match self.components.get_mut(key.id).and_then(|v| v.as_mut()) { Some(val) => val, None => return None, }; let set = match self.entities.get(entity.id).as_ref() { - Some(val) => if val.1 == entity.generation { &val.0 } else { return None }, + Some(val) => { + if val.1 == entity.generation { + &val.0 + } else { + return None; + } + } None => return None, }; if !set.as_ref().map_or(false, |v| v.components.get(key.id)) { @@ -460,7 +571,10 @@ impl Manager { /// Same as `get_component_mut` but doesn't require a key. Using a key /// is better for frequent lookups. - pub fn get_component_mut_direct<'a, 'b: 'a, T: Any>(&'a mut self, entity: Entity) -> Option<&'b mut T> { + pub fn get_component_mut_direct<'a, 'b: 'a, T: Any>( + &'a mut self, + entity: Entity, + ) -> Option<&'b mut T> { let key = self.get_key(); self.get_component_mut(entity, key) } @@ -479,12 +593,10 @@ impl ComponentMem { ComponentMem { data: vec![], component_size: mem::size_of::(), - drop_func: Box::new(|data| { - unsafe { - let mut val: T = mem::MaybeUninit::uninit().assume_init(); - ptr::copy(data as *mut T, &mut val, 1); - mem::drop(val); - } + drop_func: Box::new(|data| unsafe { + let mut val: T = mem::MaybeUninit::uninit().assume_init(); + ptr::copy(data as *mut T, &mut val, 1); + mem::drop(val); }), } } @@ -496,7 +608,11 @@ impl ComponentMem { let idx = index / COMPONENTS_PER_BLOCK; let rem = index % COMPONENTS_PER_BLOCK; if self.data[idx].is_none() { - self.data[idx] = Some((vec![0; self.component_size * COMPONENTS_PER_BLOCK], BSet::new(COMPONENTS_PER_BLOCK), 0)); + self.data[idx] = Some(( + vec![0; self.component_size * COMPONENTS_PER_BLOCK], + BSet::new(COMPONENTS_PER_BLOCK), + 0, + )); } let data = self.data[idx].as_mut().unwrap(); let start = rem * self.component_size; @@ -518,7 +634,9 @@ impl ComponentMem { // We don't have access to the actual type in this method so // we use the drop_func which stores the type in its closure // to handle the dropping for us. - unsafe { (self.drop_func)(data.0.as_mut_ptr().offset(start as isize)); } + unsafe { + (self.drop_func)(data.0.as_mut_ptr().offset(start as isize)); + } data.2 -= 1; data.2 }; @@ -532,9 +650,7 @@ impl ComponentMem { let rem = index % COMPONENTS_PER_BLOCK; let data = self.data[idx].as_ref().unwrap(); let start = rem * self.component_size; - unsafe { - &*(data.0.as_ptr().offset(start as isize) as *const T) - } + unsafe { &*(data.0.as_ptr().offset(start as isize) as *const T) } } fn get_mut(&mut self, index: usize) -> &mut T { @@ -542,9 +658,7 @@ impl ComponentMem { let rem = index % COMPONENTS_PER_BLOCK; let data = self.data[idx].as_mut().unwrap(); let start = rem * self.component_size; - unsafe { - &mut *(data.0.as_mut_ptr().offset(start as isize) as *mut T) - } + unsafe { &mut *(data.0.as_mut_ptr().offset(start as isize) as *mut T) } } } @@ -552,10 +666,12 @@ impl Drop for ComponentMem { fn drop(&mut self) { for data in &mut self.data { if let Some(data) = data.as_mut() { - for i in 0 .. COMPONENTS_PER_BLOCK { + for i in 0..COMPONENTS_PER_BLOCK { if data.1.get(i) { let start = i * self.component_size; - unsafe { (self.drop_func)(data.0.as_mut_ptr().offset(start as isize)); } + unsafe { + (self.drop_func)(data.0.as_mut_ptr().offset(start as isize)); + } } } } diff --git a/src/entity/block_entity/mod.rs b/src/entity/block_entity/mod.rs index 9a1b55b..82305ae 100644 --- a/src/entity/block_entity/mod.rs +++ b/src/entity/block_entity/mod.rs @@ -1,22 +1,21 @@ - pub mod sign; -use crate::world::block::Block; -use crate::shared::Position; use crate::ecs; +use crate::shared::Position; +use crate::world::block::Block; pub fn add_systems(m: &mut ecs::Manager) { sign::add_systems(m); } pub enum BlockEntityType { - Sign + Sign, } impl BlockEntityType { pub fn get_block_entity(bl: Block) -> Option { match bl { - Block::StandingSign{..} | Block::WallSign{..} => Some(BlockEntityType::Sign), + Block::StandingSign { .. } | Block::WallSign { .. } => Some(BlockEntityType::Sign), _ => None, } } diff --git a/src/entity/block_entity/sign.rs b/src/entity/block_entity/sign.rs index 8171fbf..eaf650a 100644 --- a/src/entity/block_entity/sign.rs +++ b/src/entity/block_entity/sign.rs @@ -1,11 +1,10 @@ - use crate::ecs; use crate::format::{self, Component}; +use crate::render; +use crate::render::model::{self, FormatState}; use crate::shared::{Direction, Position}; use crate::world; use crate::world::block::Block; -use crate::render; -use crate::render::model::{self, FormatState}; pub fn add_systems(m: &mut ecs::Manager) { let sys = SignRenderer::new(m); @@ -13,21 +12,24 @@ pub fn add_systems(m: &mut ecs::Manager) { } pub fn init_entity(m: &mut ecs::Manager, e: ecs::Entity) { - m.add_component_direct(e, SignInfo { - model: None, - lines: [ - Component::Text(format::TextComponent::new("")), - Component::Text(format::TextComponent::new("")), - Component::Text(format::TextComponent::new("")), - Component::Text(format::TextComponent::new("")), - ], - offset_x: 0.0, - offset_y: 0.0, - offset_z: 0.0, - has_stand: false, - rotation: 0.0, - dirty: false, - }); + m.add_component_direct( + e, + SignInfo { + model: None, + lines: [ + Component::Text(format::TextComponent::new("")), + Component::Text(format::TextComponent::new("")), + Component::Text(format::TextComponent::new("")), + Component::Text(format::TextComponent::new("")), + ], + offset_x: 0.0, + offset_y: 0.0, + offset_z: 0.0, + has_stand: false, + rotation: 0.0, + dirty: false, + }, + ); } pub struct SignInfo { @@ -54,9 +56,7 @@ impl SignRenderer { let sign_info = m.get_key(); let position = m.get_key(); SignRenderer { - filter: ecs::Filter::new() - .with(position) - .with(sign_info), + filter: ecs::Filter::new().with(position).with(sign_info), position, sign_info, } @@ -64,12 +64,16 @@ impl SignRenderer { } impl ecs::System for SignRenderer { - fn filter(&self) -> &ecs::Filter { &self.filter } - fn update(&mut self, m: &mut ecs::Manager, world: &mut world::World, renderer: &mut render::Renderer) { + fn update( + &mut self, + m: &mut ecs::Manager, + world: &mut world::World, + renderer: &mut render::Renderer, + ) { for e in m.find(&self.filter) { let position = *m.get_component(e, self.position).unwrap(); let info = m.get_component_mut(e, self.sign_info).unwrap(); @@ -85,24 +89,30 @@ impl ecs::System for SignRenderer { } } - fn entity_added(&mut self, m: &mut ecs::Manager, e: ecs::Entity, world: &mut world::World, renderer: &mut render::Renderer) { + fn entity_added( + &mut self, + m: &mut ecs::Manager, + e: ecs::Entity, + world: &mut world::World, + renderer: &mut render::Renderer, + ) { + use cgmath::{Decomposed, Matrix4, Quaternion, Rad, Rotation3, Vector3}; use std::f64::consts::PI; - use cgmath::{Vector3, Matrix4, Decomposed, Rotation3, Rad, Quaternion}; let position = *m.get_component(e, self.position).unwrap(); let info = m.get_component_mut(e, self.sign_info).unwrap(); info.dirty = false; match world.get_block(position) { - Block::WallSign{facing, ..} => { + Block::WallSign { facing, .. } => { info.offset_z = 7.5 / 16.0; match facing { - Direction::North => {}, + Direction::North => {} Direction::South => info.rotation = PI, Direction::West => info.rotation = PI / 2.0, Direction::East => info.rotation = -PI / 2.0, _ => unreachable!(), } - }, - Block::StandingSign{rotation, ..} => { + } + Block::StandingSign { rotation, .. } => { info.offset_y = 5.0 / 16.0; info.has_stand = true; info.rotation = -(rotation.data() as f64 / 16.0) * PI * 2.0 + PI; @@ -112,30 +122,48 @@ impl ecs::System for SignRenderer { let tex = render::Renderer::get_texture(renderer.get_textures_ref(), "entity/sign"); macro_rules! rel { - ($x:expr, $y:expr, $w:expr, $h:expr) => ( + ($x:expr, $y:expr, $w:expr, $h:expr) => { Some(tex.relative(($x) / 64.0, ($y) / 32.0, ($w) / 64.0, ($h) / 32.0)) - ); + }; } let mut verts = vec![]; // Backboard - model::append_box(&mut verts, -0.5, -4.0/16.0, -0.5/16.0, 1.0, 8.0/16.0, 1.0/16.0, [ - rel!(26.0, 0.0, 24.0, 2.0), // Down - rel!(2.0, 0.0, 24.0, 2.0), // Up - rel!(2.0, 2.0, 24.0, 12.0), // North - rel!(26.0, 2.0, 24.0, 12.0), // South - rel!(0.0, 2.0, 2.0, 12.0), // West - rel!(50.0, 2.0, 2.0, 12.0), // East - ]); + model::append_box( + &mut verts, + -0.5, + -4.0 / 16.0, + -0.5 / 16.0, + 1.0, + 8.0 / 16.0, + 1.0 / 16.0, + [ + rel!(26.0, 0.0, 24.0, 2.0), // Down + rel!(2.0, 0.0, 24.0, 2.0), // Up + rel!(2.0, 2.0, 24.0, 12.0), // North + rel!(26.0, 2.0, 24.0, 12.0), // South + rel!(0.0, 2.0, 2.0, 12.0), // West + rel!(50.0, 2.0, 2.0, 12.0), // East + ], + ); if info.has_stand { - model::append_box(&mut verts, -0.5/16.0, -0.25-9.0/16.0, -0.5/16.0, 1.0/16.0, 9.0/16.0, 1.0/16.0, [ - rel!(4.0, 14.0, 2.0, 2.0), // Down - rel!(2.0, 14.0, 2.0, 2.0), // Up - rel!(2.0, 16.0, 2.0, 12.0), // North - rel!(6.0, 16.0, 2.0, 12.0), // South - rel!(0.0, 16.0, 2.0, 12.0), // West - rel!(4.0, 16.0, 2.0, 12.0), // East - ]); + model::append_box( + &mut verts, + -0.5 / 16.0, + -0.25 - 9.0 / 16.0, + -0.5 / 16.0, + 1.0 / 16.0, + 9.0 / 16.0, + 1.0 / 16.0, + [ + rel!(4.0, 14.0, 2.0, 2.0), // Down + rel!(2.0, 14.0, 2.0, 2.0), // Up + rel!(2.0, 16.0, 2.0, 12.0), // North + rel!(6.0, 16.0, 2.0, 12.0), // South + rel!(0.0, 16.0, 2.0, 12.0), // West + rel!(4.0, 16.0, 2.0, 12.0), // East + ], + ); } for (i, line) in info.lines.iter().enumerate() { @@ -154,15 +182,12 @@ impl ecs::System for SignRenderer { // Center align text for vert in &mut state.text { vert.x += width * 0.5; - vert.y -= (Y_SCALE + 0.4/16.0) * (i as f32); + vert.y -= (Y_SCALE + 0.4 / 16.0) * (i as f32); } verts.extend_from_slice(&state.text); } - let model = renderer.model.create_model( - model::DEFAULT, - vec![verts] - ); + let model = renderer.model.create_model(model::DEFAULT, vec![verts]); { let mdl = renderer.model.get_model(model).unwrap(); @@ -173,14 +198,28 @@ impl ecs::System for SignRenderer { mdl.matrix[0] = Matrix4::from(Decomposed { scale: 1.0, rot: Quaternion::from_angle_y(Rad(info.rotation as f32)), - disp: Vector3::new(position.x as f32 + 0.5, -position.y as f32 - 0.5, position.z as f32 + 0.5), - }) * Matrix4::from_translation(Vector3::new(info.offset_x as f32, -info.offset_y as f32, info.offset_z as f32)); + disp: Vector3::new( + position.x as f32 + 0.5, + -position.y as f32 - 0.5, + position.z as f32 + 0.5, + ), + }) * Matrix4::from_translation(Vector3::new( + info.offset_x as f32, + -info.offset_y as f32, + info.offset_z as f32, + )); } info.model = Some(model); } - fn entity_removed(&mut self, m: &mut ecs::Manager, e: ecs::Entity, _: &mut world::World, renderer: &mut render::Renderer) { + fn entity_removed( + &mut self, + m: &mut ecs::Manager, + e: ecs::Entity, + _: &mut world::World, + renderer: &mut render::Renderer, + ) { let info = m.get_component_mut(e, self.sign_info).unwrap(); if let Some(model) = info.model { renderer.model.remove_model(model); diff --git a/src/entity/mod.rs b/src/entity/mod.rs index 8b5f432..d5c80bf 100644 --- a/src/entity/mod.rs +++ b/src/entity/mod.rs @@ -1,6 +1,5 @@ - -pub mod player; pub mod block_entity; +pub mod player; use crate::ecs; use cgmath::Vector3; @@ -96,10 +95,7 @@ pub struct Rotation { impl Rotation { pub fn new(yaw: f64, pitch: f64) -> Rotation { - Rotation { - yaw, - pitch, - } + Rotation { yaw, pitch } } pub fn zero() -> Rotation { @@ -114,10 +110,7 @@ pub struct TargetRotation { impl TargetRotation { pub fn new(yaw: f64, pitch: f64) -> TargetRotation { - TargetRotation { - yaw, - pitch, - } + TargetRotation { yaw, pitch } } pub fn zero() -> TargetRotation { @@ -131,7 +124,9 @@ pub struct Gravity { } impl Gravity { - pub fn new() -> Gravity { Default::default() } + pub fn new() -> Gravity { + Default::default() + } } pub struct Bounds { @@ -140,9 +135,7 @@ pub struct Bounds { impl Bounds { pub fn new(bounds: Aabb3) -> Bounds { - Bounds { - bounds, - } + Bounds { bounds } } } @@ -152,7 +145,9 @@ pub struct GameInfo { } impl GameInfo { - pub fn new() -> GameInfo { Default::default() } + pub fn new() -> GameInfo { + Default::default() + } } #[derive(Default)] @@ -162,5 +157,7 @@ pub struct Light { } impl Light { - pub fn new() -> Light { Default::default() } + pub fn new() -> Light { + Default::default() + } } diff --git a/src/entity/player.rs b/src/entity/player.rs index 4e42470..997115f 100644 --- a/src/entity/player.rs +++ b/src/entity/player.rs @@ -1,29 +1,20 @@ - -use crate::ecs; use super::{ - Position, - TargetPosition, - Velocity, - Rotation, - TargetRotation, - Gravity, - Bounds, - GameInfo, - Light + Bounds, GameInfo, Gravity, Light, Position, Rotation, TargetPosition, TargetRotation, Velocity, }; -use crate::world; +use crate::ecs; +use crate::format; use crate::render; use crate::render::model::{self, FormatState}; +use crate::settings::Stevenkey; +use crate::shared::Position as BPosition; +use crate::types::hash::FNVHash; use crate::types::Gamemode; +use crate::world; +use cgmath::{self, Decomposed, Matrix4, Point3, Quaternion, Rad, Rotation3, Vector3}; use collision::{Aabb, Aabb3}; -use cgmath::{self, Point3, Vector3, Matrix4, Decomposed, Rotation3, Rad, Quaternion}; use std::collections::HashMap; use std::hash::BuildHasherDefault; use std::time::Instant; -use crate::types::hash::FNVHash; -use crate::settings::Stevenkey; -use crate::shared::Position as BPosition; -use crate::format; pub fn add_systems(m: &mut ecs::Manager) { let sys = MovementHandler::new(m); @@ -43,10 +34,13 @@ pub fn create_local(m: &mut ecs::Manager) -> ecs::Entity { m.add_component_direct(entity, Gamemode::Survival); m.add_component_direct(entity, Gravity::new()); m.add_component_direct(entity, PlayerMovement::new()); - m.add_component_direct(entity, Bounds::new(Aabb3::new( - Point3::new(-0.3, 0.0, -0.3), - Point3::new(0.3, 1.8, 0.3) - ))); + m.add_component_direct( + entity, + Bounds::new(Aabb3::new( + Point3::new(-0.3, 0.0, -0.3), + Point3::new(0.3, 1.8, 0.3), + )), + ); m.add_component_direct(entity, PlayerModel::new("", false, false, true)); m.add_component_direct(entity, Light::new()); entity @@ -59,16 +53,18 @@ pub fn create_remote(m: &mut ecs::Manager, name: &str) -> ecs::Entity { m.add_component_direct(entity, Rotation::new(0.0, 0.0)); m.add_component_direct(entity, TargetRotation::new(0.0, 0.0)); m.add_component_direct(entity, Velocity::new(0.0, 0.0, 0.0)); - m.add_component_direct(entity, Bounds::new(Aabb3::new( - Point3::new(-0.3, 0.0, -0.3), - Point3::new(0.3, 1.8, 0.3) - ))); + m.add_component_direct( + entity, + Bounds::new(Aabb3::new( + Point3::new(-0.3, 0.0, -0.3), + Point3::new(0.3, 1.8, 0.3), + )), + ); m.add_component_direct(entity, PlayerModel::new(name, true, true, false)); m.add_component_direct(entity, Light::new()); entity } - pub struct PlayerModel { model: Option, skin_url: Option, @@ -155,16 +151,23 @@ enum PlayerModelPart { // TODO: Setup culling impl ecs::System for PlayerRenderer { - fn filter(&self) -> &ecs::Filter { &self.filter } - fn update(&mut self, m: &mut ecs::Manager, world: &mut world::World, renderer: &mut render::Renderer) { + fn update( + &mut self, + m: &mut ecs::Manager, + world: &mut world::World, + renderer: &mut render::Renderer, + ) { use std::f32::consts::PI; use std::f64::consts::PI as PI64; let world_entity = m.get_world(); - let delta = m.get_component_mut(world_entity, self.game_info).unwrap().delta; + let delta = m + .get_component_mut(world_entity, self.game_info) + .unwrap() + .delta; for e in m.find(&self.filter) { let player_model = m.get_component_mut(e, self.player_model).unwrap(); let position = m.get_component_mut(e, self.position).unwrap(); @@ -183,8 +186,8 @@ impl ecs::System for PlayerRenderer { mdl.sky_light = light.sky_light; let offset = if player_model.first_person { - let ox = (rotation.yaw - PI64/2.0).cos() * 0.25; - let oz = -(rotation.yaw - PI64/2.0).sin() * 0.25; + let ox = (rotation.yaw - PI64 / 2.0).cos() * 0.25; + let oz = -(rotation.yaw - PI64 / 2.0).sin() * 0.25; Vector3::new( position.position.x as f32 - ox as f32, -position.position.y as f32, @@ -205,24 +208,28 @@ impl ecs::System for PlayerRenderer { // TODO This sucks if player_model.has_name_tag { - let ang = (position.position.x - renderer.camera.pos.x).atan2(position.position.z - renderer.camera.pos.z) as f32; + let ang = (position.position.x - renderer.camera.pos.x) + .atan2(position.position.z - renderer.camera.pos.z) + as f32; mdl.matrix[PlayerModelPart::NameTag as usize] = Matrix4::from(Decomposed { scale: 1.0, rot: Quaternion::from_angle_y(Rad(ang)), - disp: offset + Vector3::new(0.0, (-24.0/16.0) - 0.6, 0.0), + disp: offset + Vector3::new(0.0, (-24.0 / 16.0) - 0.6, 0.0), }); } - mdl.matrix[PlayerModelPart::Head as usize] = offset_matrix * Matrix4::from(Decomposed { - scale: 1.0, - rot: Quaternion::from_angle_x(Rad(-rotation.pitch as f32)), - disp: Vector3::new(0.0, -12.0/16.0 - 12.0/16.0, 0.0), - }); - mdl.matrix[PlayerModelPart::Body as usize] = offset_matrix * Matrix4::from(Decomposed { - scale: 1.0, - rot: Quaternion::from_angle_x(Rad(0.0)), - disp: Vector3::new(0.0, -12.0/16.0 - 6.0/16.0, 0.0), - }); + mdl.matrix[PlayerModelPart::Head as usize] = offset_matrix + * Matrix4::from(Decomposed { + scale: 1.0, + rot: Quaternion::from_angle_x(Rad(-rotation.pitch as f32)), + disp: Vector3::new(0.0, -12.0 / 16.0 - 12.0 / 16.0, 0.0), + }); + mdl.matrix[PlayerModelPart::Body as usize] = offset_matrix + * Matrix4::from(Decomposed { + scale: 1.0, + rot: Quaternion::from_angle_x(Rad(0.0)), + disp: Vector3::new(0.0, -12.0 / 16.0 - 6.0 / 16.0, 0.0), + }); let mut time = player_model.time; let mut dir = player_model.dir; @@ -232,16 +239,18 @@ impl ecs::System for PlayerRenderer { } let ang = ((time / 15.0) - 1.0) * (PI64 / 4.0); - mdl.matrix[PlayerModelPart::LegRight as usize] = offset_matrix * Matrix4::from(Decomposed { - scale: 1.0, - rot: Quaternion::from_angle_x(Rad(ang as f32)), - disp: Vector3::new(2.0/16.0, -12.0/16.0, 0.0), - }); - mdl.matrix[PlayerModelPart::LegLeft as usize] = offset_matrix * Matrix4::from(Decomposed { - scale: 1.0, - rot: Quaternion::from_angle_x(Rad(-ang as f32)), - disp: Vector3::new(-2.0/16.0, -12.0/16.0, 0.0), - }); + mdl.matrix[PlayerModelPart::LegRight as usize] = offset_matrix + * Matrix4::from(Decomposed { + scale: 1.0, + rot: Quaternion::from_angle_x(Rad(ang as f32)), + disp: Vector3::new(2.0 / 16.0, -12.0 / 16.0, 0.0), + }); + mdl.matrix[PlayerModelPart::LegLeft as usize] = offset_matrix + * Matrix4::from(Decomposed { + scale: 1.0, + rot: Quaternion::from_angle_x(Rad(-ang as f32)), + disp: Vector3::new(-2.0 / 16.0, -12.0 / 16.0, 0.0), + }); let mut i_time = player_model.idle_time; i_time += delta * 0.02; @@ -256,17 +265,31 @@ impl ecs::System for PlayerRenderer { player_model.arm_time -= delta; } - mdl.matrix[PlayerModelPart::ArmRight as usize] = offset_matrix * Matrix4::from_translation( - Vector3::new(6.0/16.0, -12.0/16.0-12.0/16.0, 0.0) - ) * Matrix4::from(Quaternion::from_angle_x(Rad(-(ang * 0.75) as f32))) - * Matrix4::from(Quaternion::from_angle_z(Rad((i_time.cos() * 0.06 - 0.06) as f32))) - * Matrix4::from(Quaternion::from_angle_x(Rad((i_time.sin() * 0.06 - ((7.5 - (player_model.arm_time-7.5).abs()) / 7.5)) as f32))); + mdl.matrix[PlayerModelPart::ArmRight as usize] = offset_matrix + * Matrix4::from_translation(Vector3::new( + 6.0 / 16.0, + -12.0 / 16.0 - 12.0 / 16.0, + 0.0, + )) + * Matrix4::from(Quaternion::from_angle_x(Rad(-(ang * 0.75) as f32))) + * Matrix4::from(Quaternion::from_angle_z(Rad( + (i_time.cos() * 0.06 - 0.06) as f32 + ))) + * Matrix4::from(Quaternion::from_angle_x(Rad((i_time.sin() * 0.06 + - ((7.5 - (player_model.arm_time - 7.5).abs()) / 7.5)) + as f32))); - mdl.matrix[PlayerModelPart::ArmLeft as usize] = offset_matrix * Matrix4::from_translation( - Vector3::new(-6.0/16.0, -12.0/16.0-12.0/16.0, 0.0) - ) * Matrix4::from(Quaternion::from_angle_x(Rad((ang * 0.75) as f32))) - * Matrix4::from(Quaternion::from_angle_z(Rad(-(i_time.cos() * 0.06 - 0.06) as f32))) - * Matrix4::from(Quaternion::from_angle_x(Rad(-(i_time.sin() * 0.06) as f32))); + mdl.matrix[PlayerModelPart::ArmLeft as usize] = offset_matrix + * Matrix4::from_translation(Vector3::new( + -6.0 / 16.0, + -12.0 / 16.0 - 12.0 / 16.0, + 0.0, + )) + * Matrix4::from(Quaternion::from_angle_x(Rad((ang * 0.75) as f32))) + * Matrix4::from(Quaternion::from_angle_z(Rad( + -(i_time.cos() * 0.06 - 0.06) as f32 + ))) + * Matrix4::from(Quaternion::from_angle_x(Rad(-(i_time.sin() * 0.06) as f32))); let mut update = true; if position.moved { @@ -297,7 +320,13 @@ impl ecs::System for PlayerRenderer { } } - fn entity_added(&mut self, m: &mut ecs::Manager, e: ecs::Entity, _: &mut world::World, renderer: &mut render::Renderer) { + fn entity_added( + &mut self, + m: &mut ecs::Manager, + e: ecs::Entity, + _: &mut world::World, + renderer: &mut render::Renderer, + ) { let player_model = m.get_component_mut(e, self.player_model).unwrap(); player_model.dirty = false; @@ -309,76 +338,133 @@ impl ecs::System for PlayerRenderer { }; macro_rules! srel { - ($x:expr, $y:expr, $w:expr, $h:expr) => ( + ($x:expr, $y:expr, $w:expr, $h:expr) => { Some(skin.relative(($x) / 64.0, ($y) / 64.0, ($w) / 64.0, ($h) / 64.0)) - ); + }; } let mut head_verts = vec![]; if player_model.has_head { - model::append_box(&mut head_verts, -4.0/16.0, 0.0, -4.0/16.0, 8.0/16.0, 8.0/16.0, 8.0/16.0, [ - srel!(16.0, 0.0, 8.0, 8.0), // Down - srel!(8.0, 0.0, 8.0, 8.0), // Up - srel!(8.0, 8.0, 8.0, 8.0), // North - srel!(24.0, 8.0, 8.0, 8.0), // South - srel!(16.0, 8.0, 8.0, 8.0), // West - srel!(0.0, 8.0, 8.0, 8.0), // East - ]); - model::append_box(&mut head_verts, -4.2/16.0, -0.2/16.0, -4.2/16.0, 8.4/16.0, 8.4/16.0, 8.4/16.0, [ - srel!((16.0 + 32.0), 0.0, 8.0, 8.0), // Down - srel!((8.0 + 32.0), 0.0, 8.0, 8.0), // Up - srel!((8.0 + 32.0), 8.0, 8.0, 8.0), // North - srel!((24.0 + 32.0), 8.0, 8.0, 8.0), // South - srel!((16.0 + 32.0), 8.0, 8.0, 8.0), // West - srel!((0.0 + 32.0), 8.0, 8.0, 8.0), // East - ]); + model::append_box( + &mut head_verts, + -4.0 / 16.0, + 0.0, + -4.0 / 16.0, + 8.0 / 16.0, + 8.0 / 16.0, + 8.0 / 16.0, + [ + srel!(16.0, 0.0, 8.0, 8.0), // Down + srel!(8.0, 0.0, 8.0, 8.0), // Up + srel!(8.0, 8.0, 8.0, 8.0), // North + srel!(24.0, 8.0, 8.0, 8.0), // South + srel!(16.0, 8.0, 8.0, 8.0), // West + srel!(0.0, 8.0, 8.0, 8.0), // East + ], + ); + model::append_box( + &mut head_verts, + -4.2 / 16.0, + -0.2 / 16.0, + -4.2 / 16.0, + 8.4 / 16.0, + 8.4 / 16.0, + 8.4 / 16.0, + [ + srel!((16.0 + 32.0), 0.0, 8.0, 8.0), // Down + srel!((8.0 + 32.0), 0.0, 8.0, 8.0), // Up + srel!((8.0 + 32.0), 8.0, 8.0, 8.0), // North + srel!((24.0 + 32.0), 8.0, 8.0, 8.0), // South + srel!((16.0 + 32.0), 8.0, 8.0, 8.0), // West + srel!((0.0 + 32.0), 8.0, 8.0, 8.0), // East + ], + ); } // TODO: Cape let mut body_verts = vec![]; - model::append_box(&mut body_verts, -4.0/16.0, -6.0/16.0, -2.0/16.0, 8.0/16.0, 12.0/16.0, 4.0/16.0, [ - srel!(28.0, 16.0, 8.0, 4.0), // Down - srel!(20.0, 16.0, 8.0, 4.0), // Up - srel!(20.0, 20.0, 8.0, 12.0), // North - srel!(32.0, 20.0, 8.0, 12.0), // South - srel!(16.0, 20.0, 4.0, 12.0), // West - srel!(28.0, 20.0, 4.0, 12.0), // East - ]); - model::append_box(&mut body_verts, -4.2/16.0, -6.2/16.0, -2.2/16.0, 8.4/16.0, 12.4/16.0, 4.4/16.0, [ - srel!(28.0, 16.0 + 16.0, 8.0, 4.0), // Down - srel!(20.0, 16.0 + 16.0, 8.0, 4.0), // Up - srel!(20.0, 20.0 + 16.0, 8.0, 12.0), // North - srel!(32.0, 20.0 + 16.0, 8.0, 12.0), // South - srel!(16.0, 20.0 + 16.0, 4.0, 12.0), // West - srel!(28.0, 20.0 + 16.0, 4.0, 12.0), // East - ]); + model::append_box( + &mut body_verts, + -4.0 / 16.0, + -6.0 / 16.0, + -2.0 / 16.0, + 8.0 / 16.0, + 12.0 / 16.0, + 4.0 / 16.0, + [ + srel!(28.0, 16.0, 8.0, 4.0), // Down + srel!(20.0, 16.0, 8.0, 4.0), // Up + srel!(20.0, 20.0, 8.0, 12.0), // North + srel!(32.0, 20.0, 8.0, 12.0), // South + srel!(16.0, 20.0, 4.0, 12.0), // West + srel!(28.0, 20.0, 4.0, 12.0), // East + ], + ); + model::append_box( + &mut body_verts, + -4.2 / 16.0, + -6.2 / 16.0, + -2.2 / 16.0, + 8.4 / 16.0, + 12.4 / 16.0, + 4.4 / 16.0, + [ + srel!(28.0, 16.0 + 16.0, 8.0, 4.0), // Down + srel!(20.0, 16.0 + 16.0, 8.0, 4.0), // Up + srel!(20.0, 20.0 + 16.0, 8.0, 12.0), // North + srel!(32.0, 20.0 + 16.0, 8.0, 12.0), // South + srel!(16.0, 20.0 + 16.0, 4.0, 12.0), // West + srel!(28.0, 20.0 + 16.0, 4.0, 12.0), // East + ], + ); let mut part_verts = vec![vec![]; 4]; for (i, offsets) in [ - [16.0, 48.0, 0.0, 48.0], // Left left - [0.0, 16.0, 0.0, 32.0], // Right Leg + [16.0, 48.0, 0.0, 48.0], // Left left + [0.0, 16.0, 0.0, 32.0], // Right Leg [32.0, 48.0, 48.0, 48.0], // Left arm [40.0, 16.0, 40.0, 32.0], // Right arm - ].iter().enumerate() { + ] + .iter() + .enumerate() + { let (ox, oy) = (offsets[0], offsets[1]); - model::append_box(&mut part_verts[i], -2.0/16.0, -12.0/16.0, -2.0/16.0, 4.0/16.0, 12.0/16.0, 4.0/16.0, [ - srel!(ox + 8.0, oy + 0.0, 4.0, 4.0), // Down - srel!(ox + 4.0, oy + 0.0, 4.0, 4.0), // Up - srel!(ox + 4.0, oy + 4.0, 4.0, 12.0), // North - srel!(ox + 12.0, oy + 4.0, 4.0, 12.0), // South - srel!(ox + 8.0, oy + 4.0, 4.0, 12.0), // West - srel!(ox + 0.0, oy + 4.0, 4.0, 12.0), // East - ]); + model::append_box( + &mut part_verts[i], + -2.0 / 16.0, + -12.0 / 16.0, + -2.0 / 16.0, + 4.0 / 16.0, + 12.0 / 16.0, + 4.0 / 16.0, + [ + srel!(ox + 8.0, oy + 0.0, 4.0, 4.0), // Down + srel!(ox + 4.0, oy + 0.0, 4.0, 4.0), // Up + srel!(ox + 4.0, oy + 4.0, 4.0, 12.0), // North + srel!(ox + 12.0, oy + 4.0, 4.0, 12.0), // South + srel!(ox + 8.0, oy + 4.0, 4.0, 12.0), // West + srel!(ox + 0.0, oy + 4.0, 4.0, 12.0), // East + ], + ); let (ox, oy) = (offsets[2], offsets[3]); - model::append_box(&mut part_verts[i], -2.2/16.0, -12.2/16.0, -2.2/16.0, 4.4/16.0, 12.4/16.0, 4.4/16.0, [ - srel!(ox + 8.0, oy + 0.0, 4.0, 4.0), // Down - srel!(ox + 4.0, oy + 0.0, 4.0, 4.0), // Up - srel!(ox + 4.0, oy + 4.0, 4.0, 12.0), // North - srel!(ox + 12.0, oy + 4.0, 4.0, 12.0), // South - srel!(ox + 8.0, oy + 4.0, 4.0, 12.0), // West - srel!(ox + 0.0, oy + 4.0, 4.0, 12.0), // East - ]); + model::append_box( + &mut part_verts[i], + -2.2 / 16.0, + -12.2 / 16.0, + -2.2 / 16.0, + 4.4 / 16.0, + 12.4 / 16.0, + 4.4 / 16.0, + [ + srel!(ox + 8.0, oy + 0.0, 4.0, 4.0), // Down + srel!(ox + 4.0, oy + 0.0, 4.0, 4.0), // Up + srel!(ox + 4.0, oy + 4.0, 4.0, 12.0), // North + srel!(ox + 12.0, oy + 4.0, 4.0, 12.0), // South + srel!(ox + 8.0, oy + 4.0, 4.0, 12.0), // West + srel!(ox + 0.0, oy + 4.0, 4.0, 12.0), // East + ], + ); } let mut name_verts = vec![]; @@ -423,17 +509,27 @@ impl ecs::System for PlayerRenderer { part_verts[1].clone(), part_verts[2].clone(), part_verts[3].clone(), - name_verts - ] + name_verts, + ], )); } - fn entity_removed(&mut self, m: &mut ecs::Manager, e: ecs::Entity, _: &mut world::World, renderer: &mut render::Renderer) { + fn entity_removed( + &mut self, + m: &mut ecs::Manager, + e: ecs::Entity, + _: &mut world::World, + renderer: &mut render::Renderer, + ) { let player_model = m.get_component_mut(e, self.player_model).unwrap(); if let Some(model) = player_model.model.take() { renderer.model.remove_model(model); if let Some(url) = player_model.skin_url.as_ref() { - renderer.get_textures_ref().read().unwrap().release_skin(url); + renderer + .get_textures_ref() + .read() + .unwrap() + .release_skin(url); } } } @@ -450,12 +546,14 @@ pub struct PlayerMovement { } impl PlayerMovement { - pub fn new() -> PlayerMovement { Default::default() } + pub fn new() -> PlayerMovement { + Default::default() + } fn calculate_movement(&self, player_yaw: f64) -> (f64, f64) { use std::f64::consts::PI; let mut forward = 0.0f64; - let mut yaw = player_yaw - (PI/2.0); + let mut yaw = player_yaw - (PI / 2.0); if self.is_key_pressed(Stevenkey::Forward) || self.is_key_pressed(Stevenkey::Backward) { forward = 1.0; if self.is_key_pressed(Stevenkey::Backward) { @@ -466,7 +564,9 @@ impl PlayerMovement { (PI / 2.0) / (forward.abs() + 1.0) } else if self.is_key_pressed(Stevenkey::Right) { -(PI / 2.0) / (forward.abs() + 1.0) - } else { 0.0 }; + } else { + 0.0 + }; if self.is_key_pressed(Stevenkey::Left) || self.is_key_pressed(Stevenkey::Right) { forward = 1.0; } @@ -521,7 +621,6 @@ impl MovementHandler { } impl ecs::System for MovementHandler { - fn filter(&self) -> &ecs::Filter { &self.filter } @@ -542,8 +641,11 @@ impl ecs::System for MovementHandler { if movement.when_last_jump_pressed.is_none() { movement.when_last_jump_pressed = Some(Instant::now()); if !movement.when_last_jump_released.is_none() { - let dt = movement.when_last_jump_pressed.unwrap() - movement.when_last_jump_released.unwrap(); - if dt.as_secs() == 0 && dt.subsec_millis() <= crate::settings::DOUBLE_JUMP_MS { + let dt = movement.when_last_jump_pressed.unwrap() + - movement.when_last_jump_released.unwrap(); + if dt.as_secs() == 0 + && dt.subsec_millis() <= crate::settings::DOUBLE_JUMP_MS + { movement.want_to_fly = !movement.want_to_fly; //info!("double jump! dt={:?} toggle want_to_fly = {}", dt, movement.want_to_fly); @@ -567,11 +669,16 @@ impl ecs::System for MovementHandler { 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 mut speed = if movement.is_key_pressed(Stevenkey::Sprint) { 0.2806 - } else { 0.21585 }; + } else { + 0.21585 + }; if movement.flying { speed *= 2.5; @@ -582,7 +689,8 @@ impl ecs::System for MovementHandler { position.position.y -= speed; } } else if gravity.as_ref().map_or(false, |v| v.on_ground) { - if movement.is_key_pressed(Stevenkey::Jump) && velocity.velocity.y.abs() < 0.001 { + if movement.is_key_pressed(Stevenkey::Jump) && velocity.velocity.y.abs() < 0.001 + { velocity.velocity.y = 0.42; } } else { @@ -604,12 +712,14 @@ impl ecs::System for MovementHandler { // We handle each axis separately to allow for a sliding // effect when pushing up against walls. - let (bounds, xhit) = check_collisions(world, position, &last_position, player_bounds); + let (bounds, xhit) = + check_collisions(world, position, &last_position, player_bounds); position.position.x = bounds.min.x + 0.3; last_position.x = position.position.x; position.position.z = target.z; - let (bounds, zhit) = check_collisions(world, position, &last_position, player_bounds); + let (bounds, zhit) = + check_collisions(world, position, &last_position, player_bounds); position.position.z = bounds.min.z + 0.3; last_position.z = position.position.z; @@ -624,8 +734,12 @@ impl ecs::System for MovementHandler { let mut oz = position.position.z; position.position.x = target.x; position.position.z = target.z; - for offset in 1 .. 9 { - let mini = player_bounds.add_v(cgmath::Vector3::new(0.0, offset as f64 / 16.0, 0.0)); + for offset in 1..9 { + let mini = player_bounds.add_v(cgmath::Vector3::new( + 0.0, + offset as f64 / 16.0, + 0.0, + )); let (_, hit) = check_collisions(world, position, &last_position, mini); if !hit { target.y += offset as f64 / 16.0; @@ -639,7 +753,8 @@ impl ecs::System for MovementHandler { } position.position.y = target.y; - let (bounds, yhit) = check_collisions(world, position, &last_position, player_bounds); + let (bounds, yhit) = + check_collisions(world, position, &last_position, player_bounds); position.position.y = bounds.min.y; last_position.y = position.position.y; if yhit { @@ -647,10 +762,8 @@ impl ecs::System for MovementHandler { } if let Some(gravity) = gravity { - let ground = Aabb3::new( - Point3::new(-0.3, -0.005, -0.3), - Point3::new(0.3, 0.0, 0.3) - ); + let ground = + Aabb3::new(Point3::new(-0.3, -0.005, -0.3), Point3::new(0.3, 0.0, 0.3)); let prev = gravity.on_ground; let (_, hit) = check_collisions(world, position, &last_position, ground); gravity.on_ground = hit; @@ -664,8 +777,12 @@ impl ecs::System for MovementHandler { } } - -fn check_collisions(world: &world::World, position: &mut TargetPosition, last_position: &Vector3, bounds: Aabb3) -> (Aabb3, bool) { +fn check_collisions( + world: &world::World, + position: &mut TargetPosition, + last_position: &Vector3, + bounds: Aabb3, +) -> (Aabb3, bool) { let mut bounds = bounds.add_v(position.position); let dir = position.position - last_position; @@ -678,9 +795,9 @@ fn check_collisions(world: &world::World, position: &mut TargetPosition, last_po let max_z = (bounds.max.z + 1.0) as i32; let mut hit = false; - for y in min_y .. max_y { - for z in min_z .. max_z { - for x in min_x .. max_x { + for y in min_y..max_y { + for z in min_z..max_z { + for x in min_x..max_x { let block = world.get_block(BPosition::new(x, y, z)); if block.get_material().collidable { for bb in block.get_collision_boxes() { @@ -705,14 +822,12 @@ trait Collidable { impl Collidable> for Aabb3 { fn collides(&self, t: &Aabb3) -> bool { - !( - t.min.x >= self.max.x || - t.max.x <= self.min.x || - t.min.y >= self.max.y || - t.max.y <= self.min.y || - t.min.z >= self.max.z || - t.max.z <= self.min.z - ) + !(t.min.x >= self.max.x + || t.max.x <= self.min.x + || t.min.y >= self.max.y + || t.max.y <= self.min.y + || t.min.z >= self.max.z + || t.max.z <= self.min.z) } fn move_out_of(mut self, other: Self, dir: cgmath::Vector3) -> Self { diff --git a/src/entity/systems.rs b/src/entity/systems.rs index 06b9fe1..dbb56ec 100644 --- a/src/entity/systems.rs +++ b/src/entity/systems.rs @@ -1,9 +1,8 @@ - use super::*; use crate::ecs; -use crate::world; use crate::render; use crate::shared::Position as BPos; +use crate::world; use cgmath::InnerSpace; pub struct ApplyVelocity { @@ -18,9 +17,7 @@ impl ApplyVelocity { let position = m.get_key(); let velocity = m.get_key(); ApplyVelocity { - filter: ecs::Filter::new() - .with(position) - .with(velocity), + filter: ecs::Filter::new().with(position).with(velocity), position, velocity, movement: m.get_key(), @@ -29,7 +26,6 @@ impl ApplyVelocity { } impl ecs::System for ApplyVelocity { - fn filter(&self) -> &ecs::Filter { &self.filter } @@ -58,9 +54,7 @@ impl ApplyGravity { let gravity = m.get_key::(); let velocity = m.get_key(); ApplyGravity { - filter: ecs::Filter::new() - .with(gravity) - .with(velocity), + filter: ecs::Filter::new().with(gravity).with(velocity), velocity, movement: m.get_key(), } @@ -68,7 +62,6 @@ impl ApplyGravity { } impl ecs::System for ApplyGravity { - fn filter(&self) -> &ecs::Filter { &self.filter } @@ -98,15 +91,13 @@ impl UpdateLastPosition { pub fn new(m: &mut ecs::Manager) -> UpdateLastPosition { let position = m.get_key(); UpdateLastPosition { - filter: ecs::Filter::new() - .with(position), + filter: ecs::Filter::new().with(position), position, } } } impl ecs::System for UpdateLastPosition { - fn filter(&self) -> &ecs::Filter { &self.filter } @@ -133,9 +124,7 @@ impl LerpPosition { let position = m.get_key(); let target_position = m.get_key(); LerpPosition { - filter: ecs::Filter::new() - .with(position) - .with(target_position), + filter: ecs::Filter::new().with(position).with(target_position), position, target_position, game_info: m.get_key(), @@ -144,20 +133,24 @@ impl LerpPosition { } impl ecs::System for LerpPosition { - fn filter(&self) -> &ecs::Filter { &self.filter } fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) { let world_entity = m.get_world(); - let delta = m.get_component_mut(world_entity, self.game_info).unwrap().delta.min(5.0); + let delta = m + .get_component_mut(world_entity, self.game_info) + .unwrap() + .delta + .min(5.0); for e in m.find(&self.filter) { let pos = m.get_component_mut(e, self.position).unwrap(); let target_pos = m.get_component(e, self.target_position).unwrap(); - pos.position = pos.position + (target_pos.position - pos.position) * delta * target_pos.lerp_amount; - let len = (pos.position - target_pos.position).magnitude2() ; + pos.position = pos.position + + (target_pos.position - pos.position) * delta * target_pos.lerp_amount; + let len = (pos.position - target_pos.position).magnitude2(); if len < 0.001 || len > 100.0 * 100.0 { pos.position = target_pos.position; } @@ -177,9 +170,7 @@ impl LerpRotation { let rotation = m.get_key(); let target_rotation = m.get_key(); LerpRotation { - filter: ecs::Filter::new() - .with(rotation) - .with(target_rotation), + filter: ecs::Filter::new().with(rotation).with(target_rotation), rotation, target_rotation, game_info: m.get_key(), @@ -188,7 +179,6 @@ impl LerpRotation { } impl ecs::System for LerpRotation { - fn filter(&self) -> &ecs::Filter { &self.filter } @@ -196,12 +186,16 @@ impl ecs::System for LerpRotation { fn update(&mut self, m: &mut ecs::Manager, _: &mut world::World, _: &mut render::Renderer) { use std::f64::consts::PI; let world_entity = m.get_world(); - let delta = m.get_component_mut(world_entity, self.game_info).unwrap().delta.min(5.0); + let delta = m + .get_component_mut(world_entity, self.game_info) + .unwrap() + .delta + .min(5.0); for e in m.find(&self.filter) { let rot = m.get_component_mut(e, self.rotation).unwrap(); let target_rot = m.get_component_mut(e, self.target_rotation).unwrap(); - target_rot.yaw = (PI*2.0 + target_rot.yaw) % (PI*2.0); - target_rot.pitch = (PI*2.0 + target_rot.pitch) % (PI*2.0); + target_rot.yaw = (PI * 2.0 + target_rot.yaw) % (PI * 2.0); + target_rot.pitch = (PI * 2.0 + target_rot.pitch) % (PI * 2.0); let mut delta_yaw = target_rot.yaw - rot.yaw; let mut delta_pitch = target_rot.pitch - rot.pitch; @@ -215,8 +209,8 @@ impl ecs::System for LerpRotation { rot.yaw += delta_yaw * 0.2 * delta; rot.pitch += delta_pitch * 0.2 * delta; - rot.yaw = (PI*2.0 + rot.yaw) % (PI*2.0); - rot.pitch = (PI*2.0 + rot.pitch) % (PI*2.0); + rot.yaw = (PI * 2.0 + rot.yaw) % (PI * 2.0); + rot.pitch = (PI * 2.0 + rot.pitch) % (PI * 2.0); } } } @@ -225,7 +219,7 @@ pub struct LightEntity { filter: ecs::Filter, position: ecs::Key, bounds: ecs::Key, - light: ecs::Key + light: ecs::Key, } impl LightEntity { @@ -234,10 +228,7 @@ impl LightEntity { let bounds = m.get_key(); let light = m.get_key(); LightEntity { - filter: ecs::Filter::new() - .with(position) - .with(bounds) - .with(light), + filter: ecs::Filter::new().with(position).with(bounds).with(light), position, bounds, light, @@ -246,7 +237,6 @@ impl LightEntity { } impl ecs::System for LightEntity { - fn filter(&self) -> &ecs::Filter { &self.filter } @@ -269,14 +259,13 @@ impl ecs::System for LightEntity { let length = (bounds.bounds.max - bounds.bounds.min).magnitude() as f32; - for y in min_y .. max_y { - for z in min_z .. max_z { - for x in min_x .. max_x { - let dist = length - ( - ((x as f32 + 0.5) - pos.position.x as f32).powi(2) + for y in min_y..max_y { + for z in min_z..max_z { + for x in min_x..max_x { + let dist = length + - (((x as f32 + 0.5) - pos.position.x as f32).powi(2) + ((y as f32 + 0.5) - pos.position.y as f32).powi(2) - + ((z as f32 + 0.5) - pos.position.z as f32).powi(2) - ) + + ((z as f32 + 0.5) - pos.position.z as f32).powi(2)) .sqrt() .min(length); let dist = dist / length; diff --git a/src/gl/mod.rs b/src/gl/mod.rs index e306012..52e6b8a 100644 --- a/src/gl/mod.rs +++ b/src/gl/mod.rs @@ -14,15 +14,15 @@ extern crate steven_gl as gl; -use std::ops::BitOr; +use log::{error, info}; use std::ffi; use std::mem; -use std::ptr; +use std::ops::BitOr; use std::ops::{Deref, DerefMut}; -use log::{error, info}; +use std::ptr; /// Inits the gl library. This should be called once a context is ready. -pub fn init(vid: & glutin::WindowedContext) { +pub fn init(vid: &glutin::WindowedContext) { gl::load_with(|s| vid.get_proc_address(s) as *const _); } @@ -54,7 +54,13 @@ pub fn draw_elements(ty: DrawType, count: i32, dty: Type, offset: usize) { pub fn multi_draw_elements(ty: DrawType, count: &[i32], dty: Type, offsets: &[usize]) { unsafe { - gl::MultiDrawElements(ty, count.as_ptr(), dty, offsets.as_ptr() as *const _, count.len() as i32); + gl::MultiDrawElements( + ty, + count.as_ptr(), + dty, + offsets.as_ptr() as *const _, + count.len() as i32, + ); } } @@ -107,7 +113,9 @@ pub fn clear(flags: ClearFlags) { } pub fn depth_mask(f: bool) { - unsafe { gl::DepthMask(f as u8); } + unsafe { + gl::DepthMask(f as u8); + } } /// `Func` is a function to be preformed on two values. @@ -171,7 +179,12 @@ pub fn blend_func(s_factor: Factor, d_factor: Factor) { } } -pub fn blend_func_separate(s_factor_rgb: Factor, d_factor_rgb: Factor, s_factor_a: Factor, d_factor_a: Factor) { +pub fn blend_func_separate( + s_factor_rgb: Factor, + d_factor_rgb: Factor, + s_factor_a: Factor, + d_factor_a: Factor, +) { unsafe { gl::BlendFuncSeparate(s_factor_rgb, d_factor_rgb, s_factor_a, d_factor_a); } @@ -270,180 +283,208 @@ impl Texture { } } - pub fn get_pixels(&self, - target: TextureTarget, - level: i32, - format: TextureFormat, - ty: Type, - pixels: &mut [u8]) { + pub fn get_pixels( + &self, + target: TextureTarget, + level: i32, + format: TextureFormat, + ty: Type, + pixels: &mut [u8], + ) { unsafe { - gl::GetTexImage(target, - level, - format, - ty, - pixels.as_mut_ptr() as *mut gl::types::GLvoid); + gl::GetTexImage( + target, + level, + format, + ty, + pixels.as_mut_ptr() as *mut gl::types::GLvoid, + ); } } - pub fn image_2d(&self, - target: TextureTarget, - level: i32, - width: u32, - height: u32, - format: TextureFormat, - ty: Type, - pix: Option<&[u8]>) { + pub fn image_2d( + &self, + target: TextureTarget, + level: i32, + width: u32, + height: u32, + format: TextureFormat, + ty: Type, + pix: Option<&[u8]>, + ) { unsafe { let ptr = match pix { Some(val) => val.as_ptr() as *const gl::types::GLvoid, None => ptr::null(), }; - gl::TexImage2D(target, - level, - format as i32, - width as i32, - height as i32, - 0, - format, - ty, - ptr + gl::TexImage2D( + target, + level, + format as i32, + width as i32, + height as i32, + 0, + format, + ty, + ptr, ); } } - pub fn sub_image_2d(&self, - target: TextureTarget, - level: i32, - x: u32, - y: u32, - width: u32, - height: u32, - format: TextureFormat, - ty: Type, - pix: &[u8]) { + pub fn sub_image_2d( + &self, + target: TextureTarget, + level: i32, + x: u32, + y: u32, + width: u32, + height: u32, + format: TextureFormat, + ty: Type, + pix: &[u8], + ) { unsafe { - gl::TexSubImage2D(target, - level, - x as i32, - y as i32, - width as i32, - height as i32, - format, - ty, - pix.as_ptr() as *const _ + gl::TexSubImage2D( + target, + level, + x as i32, + y as i32, + width as i32, + height as i32, + format, + ty, + pix.as_ptr() as *const _, ); } } - pub fn image_2d_ex(&self, - target: TextureTarget, - level: i32, - width: u32, - height: u32, - internal_format: TextureFormat, - format: TextureFormat, - ty: Type, - pix: Option<&[u8]>) { + pub fn image_2d_ex( + &self, + target: TextureTarget, + level: i32, + width: u32, + height: u32, + internal_format: TextureFormat, + format: TextureFormat, + ty: Type, + pix: Option<&[u8]>, + ) { unsafe { let ptr = match pix { Some(val) => val.as_ptr() as *const gl::types::GLvoid, None => ptr::null(), }; - gl::TexImage2D(target, - level, - internal_format as i32, - width as i32, - height as i32, - 0, - format, - ty, - ptr + gl::TexImage2D( + target, + level, + internal_format as i32, + width as i32, + height as i32, + 0, + format, + ty, + ptr, ); } } - pub fn image_2d_sample(&self, - target: TextureTarget, - samples: i32, - width: u32, - height: u32, - format: TextureFormat, - fixed: bool) { + pub fn image_2d_sample( + &self, + target: TextureTarget, + samples: i32, + width: u32, + height: u32, + format: TextureFormat, + fixed: bool, + ) { unsafe { let result: &mut [i32] = &mut [0; 1]; gl::GetIntegerv(gl::MAX_SAMPLES, &mut result[0]); - let use_samples = - if samples > result[0] { - info!("glTexImage2DMultisample: requested {} samples but GL_MAX_SAMPLES is {}", samples, result[0]); - result[0] - } else { - samples - }; + let use_samples = if samples > result[0] { + info!( + "glTexImage2DMultisample: requested {} samples but GL_MAX_SAMPLES is {}", + samples, result[0] + ); + result[0] + } else { + samples + }; - gl::TexImage2DMultisample(target, - use_samples, - format, - width as i32, - height as i32, - fixed as u8 + gl::TexImage2DMultisample( + target, + use_samples, + format, + width as i32, + height as i32, + fixed as u8, ); } } - pub fn image_3d(&self, - target: TextureTarget, - level: i32, - width: u32, - height: u32, - depth: u32, - format: TextureFormat, - ty: Type, - pix: &[u8]) { + pub fn image_3d( + &self, + target: TextureTarget, + level: i32, + width: u32, + height: u32, + depth: u32, + format: TextureFormat, + ty: Type, + pix: &[u8], + ) { unsafe { - gl::TexImage3D(target, - level, - format as i32, - width as i32, - height as i32, - depth as i32, - 0, - format, - ty, - pix.as_ptr() as *const gl::types::GLvoid); + gl::TexImage3D( + target, + level, + format as i32, + width as i32, + height as i32, + depth as i32, + 0, + format, + ty, + pix.as_ptr() as *const gl::types::GLvoid, + ); } } - pub fn sub_image_3d(&self, - target: TextureTarget, - level: i32, - x: u32, - y: u32, - z: u32, - width: u32, - height: u32, - depth: u32, - format: TextureFormat, - ty: Type, - pix: &[u8]) { + pub fn sub_image_3d( + &self, + target: TextureTarget, + level: i32, + x: u32, + y: u32, + z: u32, + width: u32, + height: u32, + depth: u32, + format: TextureFormat, + ty: Type, + pix: &[u8], + ) { unsafe { - gl::TexSubImage3D(target, - level, - x as i32, - y as i32, - z as i32, - width as i32, - height as i32, - depth as i32, - format, - ty, - pix.as_ptr() as *const gl::types::GLvoid); + gl::TexSubImage3D( + target, + level, + x as i32, + y as i32, + z as i32, + width as i32, + height as i32, + depth as i32, + format, + ty, + pix.as_ptr() as *const gl::types::GLvoid, + ); } } - pub fn set_parameter(&self, - target: TextureTarget, - param: TextureParameter, - value: TextureValue) { + pub fn set_parameter( + &self, + target: TextureTarget, + param: TextureParameter, + value: TextureValue, + ) { unsafe { gl::TexParameteri(target, param, value); } @@ -495,9 +536,8 @@ impl Program { } pub fn uniform_location(&self, name: &str) -> Option { - let u = unsafe { - gl::GetUniformLocation(self.0, ffi::CString::new(name).unwrap().as_ptr()) - }; + let u = + unsafe { gl::GetUniformLocation(self.0, ffi::CString::new(name).unwrap().as_ptr()) }; if u != -1 { Some(Uniform(u)) } else { @@ -536,10 +576,7 @@ impl Shader { pub fn set_source(&self, src: &str) { unsafe { let src_c = ffi::CString::new(src).unwrap(); - gl::ShaderSource(self.0, - 1, - &src_c.as_ptr(), - ptr::null()); + gl::ShaderSource(self.0, 1, &src_c.as_ptr(), ptr::null()); } } @@ -624,7 +661,8 @@ impl Uniform { pub fn set_matrix4_multi(&self, m: &[::cgmath::Matrix4]) { unsafe { - gl::UniformMatrix4fv(self.0, m.len() as i32, false as u8, m.as_ptr() as *const _); // TODO: Most likely isn't safe + gl::UniformMatrix4fv(self.0, m.len() as i32, false as u8, m.as_ptr() as *const _); + // TODO: Most likely isn't safe } } } @@ -647,22 +685,26 @@ impl Attribute { pub fn vertex_pointer(&self, size: i32, ty: Type, normalized: bool, stride: i32, offset: i32) { unsafe { - gl::VertexAttribPointer(self.0 as u32, - size, - ty, - normalized as u8, - stride, - offset as *const gl::types::GLvoid); + gl::VertexAttribPointer( + self.0 as u32, + size, + ty, + normalized as u8, + stride, + offset as *const gl::types::GLvoid, + ); } } pub fn vertex_pointer_int(&self, size: i32, ty: Type, stride: i32, offset: i32) { unsafe { - gl::VertexAttribIPointer(self.0 as u32, - size, - ty, - stride, - offset as *const gl::types::GLvoid); + gl::VertexAttribIPointer( + self.0 as u32, + size, + ty, + stride, + offset as *const gl::types::GLvoid, + ); } } } @@ -753,10 +795,12 @@ impl Buffer { pub fn set_data(&self, target: BufferTarget, data: &[u8], usage: BufferUsage) { unsafe { - gl::BufferData(target, - data.len() as isize, - data.as_ptr() as *const gl::types::GLvoid, - usage); + gl::BufferData( + target, + data.len() as isize, + data.as_ptr() as *const gl::types::GLvoid, + usage, + ); } } @@ -832,11 +876,12 @@ pub struct Framebuffer(u32); pub fn check_framebuffer_status() { unsafe { let status = gl::CheckFramebufferStatus(gl::FRAMEBUFFER); - let s = - match status { + let s = match status { gl::FRAMEBUFFER_UNDEFINED => "GL_FRAMEBUFFER_UNDEFINED", gl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT => "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", - gl::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT => "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", + gl::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT => { + "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" + } gl::FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER => "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER", gl::FRAMEBUFFER_INCOMPLETE_READ_BUFFER => "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER", gl::FRAMEBUFFER_UNSUPPORTED => "GL_FRAMEBUFFER_UNSUPPORTED", @@ -845,11 +890,14 @@ pub fn check_framebuffer_status() { gl::FRAMEBUFFER_COMPLETE => "GL_FRAMEBUFFER_COMPLETE", //gl::FRAMEBUFFER_INCOMPLETE_DIMENSIONS => "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS", - _ => "unknown" + _ => "unknown", }; if status != gl::FRAMEBUFFER_COMPLETE { - panic!("glBindFramebuffer failed, glCheckFrameBufferStatus(GL_FRAMEBUFFER) = {} {}", status, s); + panic!( + "glBindFramebuffer failed, glCheckFrameBufferStatus(GL_FRAMEBUFFER) = {} {}", + status, s + ); } } } @@ -859,7 +907,7 @@ pub fn check_gl_error() { loop { let err = gl::GetError(); if err == gl::NO_ERROR { - break + break; } error!("glGetError = {}", err); @@ -894,7 +942,13 @@ impl Framebuffer { } } - pub fn texture_2d(&self, attachment: Attachment, target: TextureTarget, tex: &Texture, level: i32) { + pub fn texture_2d( + &self, + attachment: Attachment, + target: TextureTarget, + tex: &Texture, + level: i32, + ) { unsafe { gl::FramebufferTexture2D(gl::FRAMEBUFFER, attachment, target, tex.0, level); } @@ -929,10 +983,7 @@ pub fn unbind_framebuffer_draw() { pub fn draw_buffers(bufs: &[Attachment]) { unsafe { - gl::DrawBuffers( - bufs.len() as i32, - bufs.as_ptr() - ); + gl::DrawBuffers(bufs.len() as i32, bufs.as_ptr()); } } @@ -944,14 +995,29 @@ pub fn bind_frag_data_location(p: &Program, cn: u32, name: &str) { } pub fn blit_framebuffer( - sx0: i32, sy0: i32, sx1: i32, sy1: i32, - dx0: i32, dy0: i32, dx1: i32, dy1: i32, - mask: ClearFlags, filter: TextureValue) { + sx0: i32, + sy0: i32, + sx1: i32, + sy1: i32, + dx0: i32, + dy0: i32, + dx1: i32, + dy1: i32, + mask: ClearFlags, + filter: TextureValue, +) { unsafe { gl::BlitFramebuffer( - sx0, sy0, sx1, sy1, - dx0, dy0, dx1, dy1, - mask.internal(), filter as u32 + sx0, + sy0, + sx1, + sy1, + dx0, + dy0, + dx1, + dy1, + mask.internal(), + filter as u32, ); } } diff --git a/src/main.rs b/src/main.rs index e366a62..12d4781 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -#![recursion_limit="300"] +#![recursion_limit = "300"] -use std::time::{Instant, Duration}; -use log::{info, warn, error}; +use log::{error, info, warn}; +use std::time::{Duration, Instant}; extern crate steven_shared as shared; use structopt::StructOpt; @@ -23,32 +23,32 @@ use structopt::StructOpt; extern crate steven_protocol; pub mod ecs; -use steven_protocol::protocol as protocol; -use steven_protocol::format as format; -use steven_protocol::nbt as nbt; +use steven_protocol::format; +use steven_protocol::nbt; +use steven_protocol::protocol; pub mod gl; -use steven_protocol::types as types; -pub mod resources; -pub mod render; -pub mod ui; -pub mod screen; -pub mod settings; -pub mod console; -pub mod server; -pub mod world; -pub mod chunk_builder; +use steven_protocol::types; pub mod auth; -pub mod model; +pub mod chunk_builder; +pub mod console; pub mod entity; +pub mod model; +pub mod render; +pub mod resources; +pub mod screen; +pub mod server; +pub mod settings; +pub mod ui; +pub mod world; -use cfg_if::cfg_if; -use std::sync::{Arc, RwLock, Mutex}; -use std::rc::Rc; -use std::marker::PhantomData; -use std::thread; -use std::sync::mpsc; use crate::protocol::mojang; +use cfg_if::cfg_if; use glutin; +use std::marker::PhantomData; +use std::rc::Rc; +use std::sync::mpsc; +use std::sync::{Arc, Mutex, RwLock}; +use std::thread; const CL_BRAND: console::CVar = console::CVar { ty: PhantomData, @@ -87,16 +87,24 @@ pub struct Game { impl Game { pub fn connect_to(&mut self, address: &str) { - let (protocol_version, forge_mods) = match protocol::Conn::new(&address, self.default_protocol_version) - .and_then(|conn| conn.do_status()) { + let (protocol_version, forge_mods) = + match protocol::Conn::new(&address, self.default_protocol_version) + .and_then(|conn| conn.do_status()) + { Ok(res) => { - info!("Detected server protocol version {}", res.0.version.protocol); + info!( + "Detected server protocol version {}", + res.0.version.protocol + ); (res.0.version.protocol, res.0.forge_mods) - }, + } Err(err) => { - warn!("Error pinging server {} to get protocol version: {:?}, defaulting to {}", address, err, self.default_protocol_version); + warn!( + "Error pinging server {} to get protocol version: {:?}, defaulting to {}", + address, err, self.default_protocol_version + ); (self.default_protocol_version, vec![]) - }, + } }; let (tx, rx) = mpsc::channel(); @@ -109,7 +117,14 @@ impl Game { access_token: self.vars.get(auth::AUTH_TOKEN).clone(), }; thread::spawn(move || { - tx.send(server::Server::connect(resources, profile, &address, protocol_version, forge_mods)).unwrap(); + tx.send(server::Server::connect( + resources, + profile, + &address, + protocol_version, + forge_mods, + )) + .unwrap(); }); } @@ -122,9 +137,8 @@ impl Game { } if let Some(disconnect_reason) = self.server.disconnect_reason.take() { - self.screen_sys.replace_screen(Box::new(screen::ServerList::new( - Some(disconnect_reason) - ))); + self.screen_sys + .replace_screen(Box::new(screen::ServerList::new(Some(disconnect_reason)))); } if !self.server.is_connected() { self.focused = false; @@ -140,7 +154,7 @@ impl Game { self.focused = true; self.server.remove(&mut self.renderer); self.server = val; - }, + } Err(err) => { let msg = match err { protocol::Error::Disconnect(val) => val, @@ -148,11 +162,10 @@ impl Game { let mut msg = format::TextComponent::new(&format!("{}", err)); msg.modifier.color = Some(format::Color::Red); format::Component::Text(msg) - }, + } }; - self.screen_sys.replace_screen(Box::new(screen::ServerList::new( - Some(msg) - ))); + self.screen_sys + .replace_screen(Box::new(screen::ServerList::new(Some(msg)))); } } } @@ -240,14 +253,19 @@ fn main2() { let window = glutin::ContextBuilder::new() .with_stencil_buffer(0) .with_depth_buffer(24) - .with_gl(glutin::GlRequest::GlThenGles{opengl_version: (3, 2), opengles_version: (2, 0)}) + .with_gl(glutin::GlRequest::GlThenGles { + opengl_version: (3, 2), + opengles_version: (2, 0), + }) .with_gl_profile(glutin::GlProfile::Core) .with_vsync(vsync) .build_windowed(window_builder, &events_loop) .expect("Could not create glutin window."); let mut window = unsafe { - window.make_current().expect("Could not set current context.") + window + .make_current() + .expect("Could not set current context.") }; gl::init(&window); @@ -271,14 +289,15 @@ fn main2() { } } - if let Some(username) = opt.username{ + if let Some(username) = opt.username { vars.set(auth::CL_USERNAME, username); } let textures = renderer.get_textures(); let dpi_factor = window.window().scale_factor(); let default_protocol_version = protocol::versions::protocol_name_to_protocol_version( - opt.default_protocol_version.unwrap_or("".to_string())); + opt.default_protocol_version.unwrap_or("".to_string()), + ); let mut game = Game { server: server::Server::dummy_server(resource_manager.clone()), focused: false, @@ -359,15 +378,24 @@ fn main2() { game.renderer.update_camera(physical_width, physical_height); game.server.world.compute_render_list(&mut game.renderer); - game.chunk_builder.tick(&mut game.server.world, &mut game.renderer, version); + game.chunk_builder + .tick(&mut game.server.world, &mut game.renderer, version); - game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container); + game.screen_sys + .tick(delta, &mut game.renderer, &mut ui_container); game.console .lock() .unwrap() .tick(&mut ui_container, &game.renderer, delta, width as f64); ui_container.tick(&mut game.renderer, delta, width as f64, height as f64); - game.renderer.tick(&mut game.server.world, delta, width, height, physical_width, physical_height); + game.renderer.tick( + &mut game.server.world, + delta, + width, + height, + physical_width, + physical_height, + ); if fps_cap > 0 && !vsync { let frame_time = now.elapsed(); @@ -384,32 +412,38 @@ fn main2() { }); } -fn handle_window_event(window: &mut glutin::WindowedContext, - game: &mut Game, - ui_container: &mut ui::Container, - event: glutin::event::Event) -> bool { +fn handle_window_event( + window: &mut glutin::WindowedContext, + game: &mut Game, + ui_container: &mut ui::Container, + event: glutin::event::Event, +) -> bool { use glutin::event::*; match event { Event::MainEventsCleared => return true, - Event::DeviceEvent{event, ..} => match event { + Event::DeviceEvent { event, .. } => match event { DeviceEvent::ModifiersChanged(modifiers_state) => { game.is_ctrl_pressed = modifiers_state.ctrl(); game.is_logo_pressed = modifiers_state.logo(); - }, + } - DeviceEvent::MouseMotion{delta:(xrel, yrel)} => { - let (rx, ry) = - if xrel > 1000.0 || yrel > 1000.0 { - // Heuristic for if we were passed an absolute value instead of relative - // Workaround https://github.com/tomaka/glutin/issues/1084 MouseMotion event returns absolute instead of relative values, when running Linux in a VM - // Note SDL2 had a hint to handle this scenario: - // sdl2::hint::set_with_priority("SDL_MOUSE_RELATIVE_MODE_WARP", "1", &sdl2::hint::Hint::Override); - let s = 8000.0 + 0.01; - ((xrel - game.last_mouse_xrel) / s, (yrel - game.last_mouse_yrel) / s) - } else { - let s = 2000.0 + 0.01; - (xrel / s, yrel / s) - }; + DeviceEvent::MouseMotion { + delta: (xrel, yrel), + } => { + let (rx, ry) = if xrel > 1000.0 || yrel > 1000.0 { + // Heuristic for if we were passed an absolute value instead of relative + // Workaround https://github.com/tomaka/glutin/issues/1084 MouseMotion event returns absolute instead of relative values, when running Linux in a VM + // Note SDL2 had a hint to handle this scenario: + // sdl2::hint::set_with_priority("SDL_MOUSE_RELATIVE_MODE_WARP", "1", &sdl2::hint::Hint::Override); + let s = 8000.0 + 0.01; + ( + (xrel - game.last_mouse_xrel) / s, + (yrel - game.last_mouse_yrel) / s, + ) + } else { + let s = 2000.0 + 0.01; + (xrel / s, yrel / s) + }; game.last_mouse_xrel = xrel; game.last_mouse_yrel = yrel; @@ -420,46 +454,57 @@ fn handle_window_event(window: &mut glutin::WindowedContext (PI/2.0)*3.0 - 0.01 { - rotation.pitch = (PI/2.0)*3.0 - 0.01; + if rotation.pitch > (PI / 2.0) * 3.0 - 0.01 { + rotation.pitch = (PI / 2.0) * 3.0 - 0.01; } } } else { window.window().set_cursor_grab(false).unwrap(); window.window().set_cursor_visible(true); } - }, - - _ => () - }, - - Event::WindowEvent{event, ..} => match event { - WindowEvent::CloseRequested => game.should_close = true, - WindowEvent::Resized(physical_size) => { - window.resize(physical_size); - }, - WindowEvent::ScaleFactorChanged{scale_factor, ..} => { - game.dpi_factor = scale_factor; } - WindowEvent::ReceivedCharacter(codepoint) => { - if !game.focused { - ui_container.key_type(game, codepoint); + _ => (), + }, + + Event::WindowEvent { event, .. } => { + match event { + WindowEvent::CloseRequested => game.should_close = true, + WindowEvent::Resized(physical_size) => { + window.resize(physical_size); + } + WindowEvent::ScaleFactorChanged { scale_factor, .. } => { + game.dpi_factor = scale_factor; } - }, - WindowEvent::MouseInput{state, button, ..} => { - match (state, button) { + WindowEvent::ReceivedCharacter(codepoint) => { + if !game.focused { + ui_container.key_type(game, codepoint); + } + } + + WindowEvent::MouseInput { state, button, .. } => match (state, button) { (ElementState::Released, MouseButton::Left) => { - let (width, height) = window.window().inner_size().to_logical::(game.dpi_factor).into(); + let (width, height) = window + .window() + .inner_size() + .to_logical::(game.dpi_factor) + .into(); - if game.server.is_connected() && !game.focused && !game.screen_sys.is_current_closable() { + if game.server.is_connected() + && !game.focused + && !game.screen_sys.is_current_closable() + { game.focused = true; window.window().set_cursor_grab(true).unwrap(); window.window().set_cursor_visible(false); @@ -467,94 +512,114 @@ fn handle_window_event(window: &mut glutin::WindowedContext { if game.focused { game.server.on_right_click(&mut game.renderer); } - }, - (_, _) => () - } - }, - WindowEvent::CursorMoved{position, ..} => { - let (x, y) = position.into(); - game.last_mouse_x = x; - game.last_mouse_y = y; + } + (_, _) => (), + }, + WindowEvent::CursorMoved { position, .. } => { + let (x, y) = position.into(); + game.last_mouse_x = x; + game.last_mouse_y = y; - if !game.focused { - let (width, height) = window.window().inner_size().to_logical::(game.dpi_factor).into(); - ui_container.hover_at(game, x, y, width, height); + if !game.focused { + let (width, height) = window + .window() + .inner_size() + .to_logical::(game.dpi_factor) + .into(); + ui_container.hover_at(game, x, y, width, height); + } } - }, - WindowEvent::MouseWheel{delta, ..} => { - // TODO: line vs pixel delta? does pixel scrolling (e.g. touchpad) need scaling? - match delta { - MouseScrollDelta::LineDelta(x, y) => { - game.screen_sys.on_scroll(x.into(), y.into()); - }, - MouseScrollDelta::PixelDelta(position) => { - let (x, y) = position.into(); - game.screen_sys.on_scroll(x, y); - }, - } - }, - WindowEvent::KeyboardInput{input, ..} => { - match (input.state, input.virtual_keycode) { - (ElementState::Released, Some(VirtualKeyCode::Escape)) => { - if game.focused { - window.window().set_cursor_grab(false).unwrap(); - window.window().set_cursor_visible(true); - game.focused = false; - game.screen_sys.replace_screen(Box::new(screen::SettingsMenu::new(game.vars.clone(), true))); - } else if game.screen_sys.is_current_closable() { - window.window().set_cursor_grab(true).unwrap(); - window.window().set_cursor_visible(false); - game.focused = true; - game.screen_sys.pop_screen(); + WindowEvent::MouseWheel { delta, .. } => { + // TODO: line vs pixel delta? does pixel scrolling (e.g. touchpad) need scaling? + match delta { + MouseScrollDelta::LineDelta(x, y) => { + game.screen_sys.on_scroll(x.into(), y.into()); + } + MouseScrollDelta::PixelDelta(position) => { + let (x, y) = position.into(); + game.screen_sys.on_scroll(x, y); } } - (ElementState::Pressed, Some(VirtualKeyCode::Grave)) => { - game.console.lock().unwrap().toggle(); - }, - (ElementState::Pressed, Some(VirtualKeyCode::F11)) => { - if !game.is_fullscreen { - // TODO: support options for exclusive and simple fullscreen - // see https://docs.rs/glutin/0.22.0-alpha5/glutin/window/struct.Window.html#method.set_fullscreen - window.window().set_fullscreen(Some(glutin::window::Fullscreen::Borderless(window.window().current_monitor()))); - } else { - window.window().set_fullscreen(None); - } - - game.is_fullscreen = !game.is_fullscreen; - }, - (ElementState::Pressed, Some(key)) => { - if game.focused { - if let Some(steven_key) = settings::Stevenkey::get_by_keycode(key, &game.vars) { - game.server.key_press(true, steven_key); - } - } else { - let ctrl_pressed = game.is_ctrl_pressed || game.is_logo_pressed; - ui_container.key_press(game, key, true, ctrl_pressed); - } - }, - (ElementState::Released, Some(key)) => { - if game.focused { - if let Some(steven_key) = settings::Stevenkey::get_by_keycode(key, &game.vars) { - game.server.key_press(false, steven_key); - } - } else { - let ctrl_pressed = game.is_ctrl_pressed; - ui_container.key_press(game, key, false, ctrl_pressed); - } - }, - (_, None) => () } - }, - _ => () - }, + WindowEvent::KeyboardInput { input, .. } => { + match (input.state, input.virtual_keycode) { + (ElementState::Released, Some(VirtualKeyCode::Escape)) => { + if game.focused { + window.window().set_cursor_grab(false).unwrap(); + window.window().set_cursor_visible(true); + game.focused = false; + game.screen_sys.replace_screen(Box::new( + screen::SettingsMenu::new(game.vars.clone(), true), + )); + } else if game.screen_sys.is_current_closable() { + window.window().set_cursor_grab(true).unwrap(); + window.window().set_cursor_visible(false); + game.focused = true; + game.screen_sys.pop_screen(); + } + } + (ElementState::Pressed, Some(VirtualKeyCode::Grave)) => { + game.console.lock().unwrap().toggle(); + } + (ElementState::Pressed, Some(VirtualKeyCode::F11)) => { + if !game.is_fullscreen { + // TODO: support options for exclusive and simple fullscreen + // see https://docs.rs/glutin/0.22.0-alpha5/glutin/window/struct.Window.html#method.set_fullscreen + window.window().set_fullscreen(Some( + glutin::window::Fullscreen::Borderless( + window.window().current_monitor(), + ), + )); + } else { + window.window().set_fullscreen(None); + } + + game.is_fullscreen = !game.is_fullscreen; + } + (ElementState::Pressed, Some(key)) => { + if game.focused { + if let Some(steven_key) = + settings::Stevenkey::get_by_keycode(key, &game.vars) + { + game.server.key_press(true, steven_key); + } + } else { + let ctrl_pressed = game.is_ctrl_pressed || game.is_logo_pressed; + ui_container.key_press(game, key, true, ctrl_pressed); + } + } + (ElementState::Released, Some(key)) => { + if game.focused { + if let Some(steven_key) = + settings::Stevenkey::get_by_keycode(key, &game.vars) + { + game.server.key_press(false, steven_key); + } + } else { + let ctrl_pressed = game.is_ctrl_pressed; + ui_container.key_press(game, key, false, ctrl_pressed); + } + } + (_, None) => (), + } + } + _ => (), + } + } _ => (), } diff --git a/src/model/liquid.rs b/src/model/liquid.rs index 9b70e34..c701931 100644 --- a/src/model/liquid.rs +++ b/src/model/liquid.rs @@ -1,12 +1,19 @@ - -use std::io::Write; -use std::sync::{Arc, RwLock}; -use crate::world::{self, block}; -use crate::shared::Direction; use crate::model::BlockVertex; use crate::render; +use crate::shared::Direction; +use crate::world::{self, block}; +use std::io::Write; +use std::sync::{Arc, RwLock}; -pub fn render_liquid(textures: Arc>,lava: bool, snapshot: &world::Snapshot, x: i32, y: i32, z: i32, buf: &mut W) -> usize { +pub fn render_liquid( + textures: Arc>, + lava: bool, + snapshot: &world::Snapshot, + x: i32, + y: i32, + z: i32, + buf: &mut W, +) -> usize { let get_liquid = if lava { get_lava_level } else { @@ -20,17 +27,25 @@ pub fn render_liquid(textures: Arc>,lav } else { ( average_liquid_level(get_liquid, snapshot, x, y, z), - average_liquid_level(get_liquid, snapshot, x+1, y, z), - average_liquid_level(get_liquid, snapshot, x, y, z+1), - average_liquid_level(get_liquid, snapshot, x+1, y, z+1) + average_liquid_level(get_liquid, snapshot, x + 1, y, z), + average_liquid_level(get_liquid, snapshot, x, y, z + 1), + average_liquid_level(get_liquid, snapshot, x + 1, y, z + 1), ) }; let tex = match snapshot.get_block(x, y, z) { - block::Block::Water{..} => render::Renderer::get_texture(&textures, "minecraft:blocks/water_still"), - block::Block::FlowingWater{..} => render::Renderer::get_texture(&textures, "minecraft:blocks/water_flow"), - block::Block::Lava{..} => render::Renderer::get_texture(&textures, "minecraft:blocks/lava_still"), - block::Block::FlowingLava{..} => render::Renderer::get_texture(&textures, "minecraft:blocks/lava_flow"), + block::Block::Water { .. } => { + render::Renderer::get_texture(&textures, "minecraft:blocks/water_still") + } + block::Block::FlowingWater { .. } => { + render::Renderer::get_texture(&textures, "minecraft:blocks/water_flow") + } + block::Block::Lava { .. } => { + render::Renderer::get_texture(&textures, "minecraft:blocks/lava_still") + } + block::Block::FlowingLava { .. } => { + render::Renderer::get_texture(&textures, "minecraft:blocks/lava_flow") + } _ => unreachable!(), }; let ux1 = 0i16; @@ -41,8 +56,11 @@ pub fn render_liquid(textures: Arc>,lav for dir in Direction::all() { let (ox, oy, oz) = dir.get_offset(); let special = dir == Direction::Up && (tl < 8 || tr < 8 || bl < 8 || br < 8); - let block = snapshot.get_block(x+ox, y+oy, z+oz); - if special || (!block.get_material().should_cull_against && get_liquid(snapshot, x+ox, y+oy, z+oz).is_none()) { + let block = snapshot.get_block(x + ox, y + oy, z + oz); + if special + || (!block.get_material().should_cull_against + && get_liquid(snapshot, x + ox, y + oy, z + oz).is_none()) + { let verts = BlockVertex::face_by_direction(dir); for vert in verts { let mut vert = vert.clone(); @@ -64,7 +82,7 @@ pub fn render_liquid(textures: Arc>,lav (0, _) => ((16.0 / 8.0) * (bl as f32)) as i32, (_, _) => ((16.0 / 8.0) * (br as f32)) as i32, }; - vert.y = (height as f32)/16.0 + (y as f32); + vert.y = (height as f32) / 16.0 + (y as f32); } vert.x += x as f32; @@ -72,13 +90,15 @@ pub fn render_liquid(textures: Arc>,lav let (bl, sl) = super::calculate_light( snapshot, - x, y, z, + x, + y, + z, vert.x as f64, vert.y as f64, vert.z as f64, dir, !lava, - false + false, ); vert.block_light = bl; vert.sky_light = sl; @@ -106,15 +126,18 @@ pub fn render_liquid(textures: Arc>,lav fn average_liquid_level( get: fn(&world::Snapshot, i32, i32, i32) -> Option, - snapshot: &world::Snapshot, x: i32, y: i32, z: i32 + snapshot: &world::Snapshot, + x: i32, + y: i32, + z: i32, ) -> i32 { let mut level = 0; - for xx in -1 .. 1 { - for zz in -1 .. 1 { - if get(snapshot, x+xx, y+1, z+zz).is_some() { + for xx in -1..1 { + for zz in -1..1 { + if get(snapshot, x + xx, y + 1, z + zz).is_some() { return 8; } - if let Some(l) = get(snapshot, x+xx, y, z+zz) { + if let Some(l) = get(snapshot, x + xx, y, z + zz) { let nl = 7 - (l & 0x7); if nl > level { level = nl; @@ -127,14 +150,14 @@ fn average_liquid_level( fn get_water_level(snapshot: &world::Snapshot, x: i32, y: i32, z: i32) -> Option { match snapshot.get_block(x, y, z) { - block::Block::Water{level} | block::Block::FlowingWater{level} => Some(level as i32), + block::Block::Water { level } | block::Block::FlowingWater { level } => Some(level as i32), _ => None, } } fn get_lava_level(snapshot: &world::Snapshot, x: i32, y: i32, z: i32) -> Option { match snapshot.get_block(x, y, z) { - block::Block::Lava{level} | block::Block::FlowingLava{level} => Some(level as i32), + block::Block::Lava { level } | block::Block::FlowingLava { level } => Some(level as i32), _ => None, } } diff --git a/src/model/mod.rs b/src/model/mod.rs index 67f96e5..00d7459 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -1,25 +1,24 @@ - pub mod liquid; -use std::sync::{Arc, RwLock}; -use std::collections::HashMap; -use std::cell::RefCell; -use std::io::Write; -use byteorder::{WriteBytesExt, NativeEndian}; -use crate::resources; use crate::render; +use crate::resources; +use crate::shared::Direction; use crate::world; use crate::world::block::{Block, TintType}; -use crate::shared::Direction; +use byteorder::{NativeEndian, WriteBytesExt}; use serde_json; +use std::cell::RefCell; +use std::collections::HashMap; +use std::io::Write; +use std::sync::{Arc, RwLock}; -use std::hash::BuildHasherDefault; use crate::types::hash::FNVHash; -use log::{error}; +use log::error; +use std::hash::BuildHasherDefault; -use rand::Rng; -use rand::seq::SliceRandom; use image::GenericImageView; +use rand::seq::SliceRandom; +use rand::Rng; pub struct Factory { resources: Arc>, @@ -35,7 +34,7 @@ pub struct Factory { struct Key(String, String); macro_rules! try_log { - ($e:expr) => ( + ($e:expr) => { match $e { Ok(val) => val, Err(err) => { @@ -43,8 +42,8 @@ macro_rules! try_log { return false; } } - ); - (opt $e:expr) => ( + }; + (opt $e:expr) => { match $e { Ok(val) => val, Err(err) => { @@ -52,7 +51,7 @@ macro_rules! try_log { return None; } } - ); + }; } thread_local!( @@ -60,7 +59,10 @@ thread_local!( ); impl Factory { - pub fn new(resources: Arc>, textures: Arc>) -> Factory { + pub fn new( + resources: Arc>, + textures: Arc>, + ) -> Factory { Factory { grass_colors: Factory::load_biome_colors(resources.clone(), "grass"), foliage_colors: Factory::load_biome_colors(resources.clone(), "foliage"), @@ -72,7 +74,11 @@ impl Factory { } fn load_biome_colors(res: Arc>, name: &str) -> image::DynamicImage { - let mut val = match res.read().unwrap().open("minecraft", &format!("textures/colormap/{}.png", name)) { + let mut val = match res + .read() + .unwrap() + .open("minecraft", &format!("textures/colormap/{}.png", name)) + { Some(val) => val, None => return image::DynamicImage::new_rgb8(256, 256), }; @@ -87,7 +93,17 @@ impl Factory { self.foliage_colors = Factory::load_biome_colors(self.resources.clone(), "foliage"); } - fn get_model(&self, key: Key, block: Block, rng: &mut R, snapshot: &world::Snapshot, x: i32, y: i32, z: i32, buf: &mut W) -> Result { + fn get_model( + &self, + key: Key, + block: Block, + rng: &mut R, + snapshot: &world::Snapshot, + x: i32, + y: i32, + z: i32, + buf: &mut W, + ) -> Result { use std::collections::hash_map::Entry; if let Some(model) = self.models.get(&key) { if model.multipart.is_empty() { @@ -103,7 +119,7 @@ impl Factory { match entry { Entry::Occupied(e) => { return Ok(e.get().render(self, snapshot, x, y, z, buf)); - }, + } Entry::Vacant(e) => { let mut res: Option = None; for rule in &model.multipart { @@ -119,7 +135,7 @@ impl Factory { if let Some(mdl) = res { return Ok(e.insert(mdl).render(self, snapshot, x, y, z, buf)); } - }, + } }; Err(true) }); @@ -143,7 +159,7 @@ impl Factory { if !ok { return false; } - }, + } Rule::Match(ref key, ref val) => { if !block.match_multipart(key, val) { return false; @@ -154,8 +170,16 @@ impl Factory { true } - pub fn get_state_model(models: &Arc>, block: Block, rng: &mut R, - snapshot: &world::Snapshot, x: i32, y: i32, z: i32, buf: &mut W) -> usize { + pub fn get_state_model( + models: &Arc>, + block: Block, + rng: &mut R, + snapshot: &world::Snapshot, + x: i32, + y: i32, + z: i32, + buf: &mut W, + ) -> usize { let (plugin, name) = block.get_model(); let key = Key(plugin.to_owned(), name.to_owned()); let mut missing_variant; @@ -177,23 +201,32 @@ impl Factory { Err(val) => missing_variant = val, }; } - let ret = Factory::get_state_model(models, Block::Missing{}, rng, snapshot, x, y, z, buf); + let ret = Factory::get_state_model(models, Block::Missing {}, rng, snapshot, x, y, z, buf); if !missing_variant { // Still no model, replace with placeholder let mut m = models.write().unwrap(); - let model = m.models.get(&Key("steven".to_owned(), "missing_block".to_owned())).unwrap().clone(); + let model = m + .models + .get(&Key("steven".to_owned(), "missing_block".to_owned())) + .unwrap() + .clone(); m.models.insert(key, model); } ret } fn load_model(&mut self, plugin: &str, name: &str) -> bool { - let file = match self.resources.read().unwrap().open(plugin, &format!("blockstates/{}.json", name)) { + let file = match self + .resources + .read() + .unwrap() + .open(plugin, &format!("blockstates/{}.json", name)) + { Some(val) => val, None => { error!("Error missing block state for {}:{}", plugin, name); return false; - }, + } }; let mdl: serde_json::Value = try_log!(serde_json::from_reader(file)); @@ -218,14 +251,12 @@ impl Factory { if let Some(when) = rule.get("when").and_then(|v| v.as_object()) { Self::parse_rules(when, &mut rules); } - model.multipart.push(MultipartRule { - apply, - rules, - }) + model.multipart.push(MultipartRule { apply, rules }) } } - self.models.insert(Key(plugin.to_owned(), name.to_owned()), model); + self.models + .insert(Key(plugin.to_owned(), name.to_owned()), model); true } @@ -252,9 +283,7 @@ impl Factory { } fn parse_model_list(&self, plugin: &str, v: &serde_json::Value) -> Variants { - let mut variants = Variants { - models: vec![] - }; + let mut variants = Variants { models: vec![] }; if let Some(list) = v.as_array() { for val in list { if let Some(mdl) = self.parse_block_state_variant(plugin, val) { @@ -273,24 +302,35 @@ impl Factory { None => { error!("Couldn't find model name"); return None; - }, + } }; - let file = match self.resources.read().unwrap().open(plugin, &format!("models/block/{}.json", model_name)) { + let file = match self + .resources + .read() + .unwrap() + .open(plugin, &format!("models/block/{}.json", model_name)) + { Some(val) => val, None => { - error!("Couldn't find model {}", format!("models/block/{}.json", model_name)); + error!( + "Couldn't find model {}", + format!("models/block/{}.json", model_name) + ); return None; - }, + } }; let block_model: serde_json::Value = try_log!(opt serde_json::from_reader(file)); let mut model = match self.parse_model(plugin, &block_model) { Some(val) => val, None => { - error!("Failed to parse model {}", format!("models/block/{}.json", model_name)); + error!( + "Failed to parse model {}", + format!("models/block/{}.json", model_name) + ); return None; - }, + } }; model.y = v.get("y").and_then(|v| v.as_f64()).unwrap_or(0.0); @@ -303,20 +343,28 @@ impl Factory { fn parse_model(&self, plugin: &str, v: &serde_json::Value) -> Option { let parent = v.get("parent").and_then(|v| v.as_str()).unwrap_or(""); let mut model = if !parent.is_empty() && !parent.starts_with("builtin/") { - let file = match self.resources.read().unwrap().open(plugin, &format!("models/{}.json", parent)) { + let file = match self + .resources + .read() + .unwrap() + .open(plugin, &format!("models/{}.json", parent)) + { Some(val) => val, None => { error!("Couldn't find model {}", format!("models/{}.json", parent)); return None; - }, + } }; let block_model: serde_json::Value = try_log!(opt serde_json::from_reader(file)); match self.parse_model(plugin, &block_model) { Some(val) => val, None => { - error!("Failed to parse model {}", format!("models/{}.json", parent)); - return None - }, + error!( + "Failed to parse model {}", + format!("models/{}.json", parent) + ); + return None; + } } } else { RawModel { @@ -343,7 +391,9 @@ impl Factory { if let Some(textures) = v.get("textures").and_then(|v| v.as_object()) { for (k, v) in textures { - model.texture_vars.insert(k.clone(), v.as_str().unwrap_or("").to_owned()); + model + .texture_vars + .insert(k.clone(), v.as_str().unwrap_or("").to_owned()); } } @@ -367,16 +417,28 @@ impl Factory { fn parse_block_element(&self, v: &serde_json::Value) -> ModelElement { let mut element = ModelElement { - from: v.get("from").and_then(|v| v.as_array()).map(|v| [ - v[0].as_f64().unwrap(), - v[1].as_f64().unwrap(), - v[2].as_f64().unwrap() - ]).unwrap(), - to: v.get("to").and_then(|v| v.as_array()).map(|v| [ - v[0].as_f64().unwrap(), - v[1].as_f64().unwrap(), - v[2].as_f64().unwrap() - ]).unwrap(), + from: v + .get("from") + .and_then(|v| v.as_array()) + .map(|v| { + [ + v[0].as_f64().unwrap(), + v[1].as_f64().unwrap(), + v[2].as_f64().unwrap(), + ] + }) + .unwrap(), + to: v + .get("to") + .and_then(|v| v.as_array()) + .map(|v| { + [ + v[0].as_f64().unwrap(), + v[1].as_f64().unwrap(), + v[2].as_f64().unwrap(), + ] + }) + .unwrap(), shade: v.get("shade").and_then(|v| v.as_bool()).unwrap_or(false), faces: [None, None, None, None, None, None], rotation: None, @@ -390,50 +452,58 @@ impl Factory { let mut uv = [0.0, 0.0, 16.0, 16.0]; match dir { Direction::North | Direction::South => { - uv[0] = element.from[0]; - uv[2] = element.to[0]; - uv[1] = 16.0 - element.to[1]; - uv[3] = 16.0 - element.from[1]; - }, + uv[0] = element.from[0]; + uv[2] = element.to[0]; + uv[1] = 16.0 - element.to[1]; + uv[3] = 16.0 - element.from[1]; + } Direction::West | Direction::East => { - uv[0] = element.from[2]; - uv[2] = element.to[2]; - uv[1] = 16.0 - element.to[1]; - uv[3] = 16.0 - element.from[1]; - }, + uv[0] = element.from[2]; + uv[2] = element.to[2]; + uv[1] = 16.0 - element.to[1]; + uv[3] = 16.0 - element.from[1]; + } Direction::Down | Direction::Up => { - uv[0] = element.from[0]; - uv[2] = element.to[0]; - uv[1] = 16.0 - element.to[2]; - uv[3] = 16.0 - element.from[2]; - }, + uv[0] = element.from[0]; + uv[2] = element.to[0]; + uv[1] = 16.0 - element.to[2]; + uv[3] = 16.0 - element.from[2]; + } _ => unreachable!(), } uv }, - |v| [ - v[0].as_f64().unwrap(), - v[1].as_f64().unwrap(), - v[2].as_f64().unwrap(), - v[3].as_f64().unwrap() - ] + |v| { + [ + v[0].as_f64().unwrap(), + v[1].as_f64().unwrap(), + v[2].as_f64().unwrap(), + v[3].as_f64().unwrap(), + ] + }, ), - texture: face.get("texture") + texture: face + .get("texture") .and_then(|v| v.as_str()) - .map(|v| if v.starts_with('#') { - v.to_owned() - } else { - "#".to_owned() + v - }).unwrap(), + .map(|v| { + if v.starts_with('#') { + v.to_owned() + } else { + "#".to_owned() + v + } + }) + .unwrap(), cull_face: Direction::from_string( - face.get("cullface") - .and_then(|v| v.as_str()) - .unwrap_or("invalid") - ), - rotation: face.get("rotation") + face.get("cullface") + .and_then(|v| v.as_str()) + .unwrap_or("invalid"), + ), + rotation: face + .get("rotation") .and_then(|v| v.as_i64()) .map_or(0, |v| v as i32), - tint_index: face.get("tintindex") + tint_index: face + .get("tintindex") .and_then(|v| v.as_i64()) .map_or(-1, |v| v as i32), }); @@ -443,14 +513,29 @@ impl Factory { if let Some(rotation) = v.get("rotation") { element.rotation = Some(BlockRotation { - origin: rotation.get("origin").and_then(|v| v.as_array()).map_or([8.0, 8.0, 8.0], |v| [ - v[0].as_f64().unwrap(), - v[1].as_f64().unwrap(), - v[2].as_f64().unwrap() - ]), - axis: rotation.get("axis").and_then(|v| v.as_str()).unwrap_or("").to_owned(), - angle: rotation.get("angle").and_then(|v| v.as_f64()).unwrap_or(0.0), - rescale: rotation.get("rescale").and_then(|v| v.as_bool()).unwrap_or(false), + origin: rotation.get("origin").and_then(|v| v.as_array()).map_or( + [8.0, 8.0, 8.0], + |v| { + [ + v[0].as_f64().unwrap(), + v[1].as_f64().unwrap(), + v[2].as_f64().unwrap(), + ] + }, + ), + axis: rotation + .get("axis") + .and_then(|v| v.as_str()) + .unwrap_or("") + .to_owned(), + angle: rotation + .get("angle") + .and_then(|v| v.as_f64()) + .unwrap_or(0.0), + rescale: rotation + .get("rescale") + .and_then(|v| v.as_bool()) + .unwrap_or(false), }); } @@ -480,29 +565,33 @@ impl Factory { }; if raw.x > 0.0 { let o = (raw.x as i32) / 90; - processed_face.cull_face = rotate_direction(processed_face.cull_face, o, FACE_ROTATION_X, &[ - Direction::East, - Direction::West, - Direction::Invalid, - ]); - processed_face.facing = rotate_direction(processed_face.facing, o, FACE_ROTATION_X, &[ - Direction::East, - Direction::West, - Direction::Invalid, - ]); + processed_face.cull_face = rotate_direction( + processed_face.cull_face, + o, + FACE_ROTATION_X, + &[Direction::East, Direction::West, Direction::Invalid], + ); + processed_face.facing = rotate_direction( + processed_face.facing, + o, + FACE_ROTATION_X, + &[Direction::East, Direction::West, Direction::Invalid], + ); } if raw.y > 0.0 { let o = (raw.y as i32) / 90; - processed_face.cull_face = rotate_direction(processed_face.cull_face, o, FACE_ROTATION, &[ - Direction::Up, - Direction::Down, - Direction::Invalid, - ]); - processed_face.facing = rotate_direction(processed_face.facing, o, FACE_ROTATION, &[ - Direction::Up, - Direction::Down, - Direction::Invalid, - ]); + processed_face.cull_face = rotate_direction( + processed_face.cull_face, + o, + FACE_ROTATION, + &[Direction::Up, Direction::Down, Direction::Invalid], + ); + processed_face.facing = rotate_direction( + processed_face.facing, + o, + FACE_ROTATION, + &[Direction::Up, Direction::Down, Direction::Invalid], + ); } let mut verts = BlockVertex::face_by_direction(all_dirs[i]).to_vec(); @@ -523,24 +612,24 @@ impl Factory { let oy2 = uy2; match face.rotation { 270 => { - uy1 = tw*16 - ox2; - uy2 = tw*16 - ox1; + uy1 = tw * 16 - ox2; + uy2 = tw * 16 - ox1; ux1 = oy1; ux2 = oy2; - }, + } 180 => { - uy1 = th*16 - oy2; - uy2 = th*16 - oy1; - ux1 = tw*16 - ox2; - ux2 = tw*16 - ox1; - }, + uy1 = th * 16 - oy2; + uy2 = th * 16 - oy1; + ux1 = tw * 16 - ox2; + ux2 = tw * 16 - ox1; + } 90 => { uy1 = ox1; uy2 = ox2; - ux1 = th*16 - oy2; - ux2 = th*16 - oy1; - }, - _ => {}, + ux1 = th * 16 - oy2; + ux2 = th * 16 - oy1; + } + _ => {} } } @@ -583,40 +672,40 @@ impl Factory { let s = angle.sin(); let x = v.x; let z = v.z; - v.x = x*c - z*s; - v.z = z*c + x*s; + v.x = x * c - z * s; + v.z = z * c + x * s; if r.rescale { v.x *= ci; v.z *= ci; } - }, + } "x" => { let c = angle.cos(); let s = angle.sin(); let z = v.z; let y = v.y; - v.z = z*c - y*s; - v.y = y*c + z*s; + v.z = z * c - y * s; + v.y = y * c + z * s; if r.rescale { v.z *= ci; v.y *= ci; } - }, + } "z" => { let c = angle.cos(); let s = angle.sin(); let x = v.x; let y = v.y; - v.x = x*c - y*s; - v.y = y*c + x*s; + v.x = x * c - y * s; + v.y = y * c + x * s; if r.rescale { v.x *= ci; v.y *= ci; } - }, + } _ => {} } v.x += (r.origin[0] / 16.0) as f32; @@ -630,8 +719,8 @@ impl Factory { let s = rot_x.sin(); let z = v.z - 0.5; let y = v.y - 0.5; - v.z = 0.5 + (z*c - y*s); - v.y = 0.5 + (y*c + z*s); + v.z = 0.5 + (z * c - y * s); + v.y = 0.5 + (y * c + z * s); } if raw.y > 0.0 { @@ -640,8 +729,8 @@ impl Factory { let s = rot_y.sin(); let x = v.x - 0.5; let z = v.z - 0.5; - v.x = 0.5 + (x*c - z*s); - v.z = 0.5 + (z*c + x*s); + v.x = 0.5 + (x * c - z * s); + v.z = 0.5 + (z * c + x * s); } if v.toffsetx == 0 { @@ -657,35 +746,42 @@ impl Factory { } if face.rotation > 0 { - let rot_y = (-face.rotation as f64 * (::std::f64::consts::PI / 180.0)) as f32; + let rot_y = + (-face.rotation as f64 * (::std::f64::consts::PI / 180.0)) as f32; let c = rot_y.cos() as i16; let s = rot_y.sin() as i16; - let x = v.toffsetx - 8*tw; - let y = v.toffsety - 8*th; - v.toffsetx = 8*tw + (x*c - y*s); - v.toffsety = 8*th + (y*c + x*s); + let x = v.toffsetx - 8 * tw; + let y = v.toffsety - 8 * th; + v.toffsetx = 8 * tw + (x * c - y * s); + v.toffsety = 8 * th + (y * c + x * s); } - if raw.uvlock && raw.y > 0.0 - && (processed_face.facing == Direction::Up || processed_face.facing == Direction::Down) { + if raw.uvlock + && raw.y > 0.0 + && (processed_face.facing == Direction::Up + || processed_face.facing == Direction::Down) + { let rot_y = (raw.y * (::std::f64::consts::PI / 180.0)) as f32; let c = rot_y.cos() as i16; let s = rot_y.sin() as i16; - let x = v.toffsetx - 8*tw; - let y = v.toffsety - 8*th; - v.toffsetx = 8*tw + (x*c - y*s); - v.toffsety = 8*th + (y*c + x*s); + let x = v.toffsetx - 8 * tw; + let y = v.toffsety - 8 * th; + v.toffsetx = 8 * tw + (x * c - y * s); + v.toffsety = 8 * th + (y * c + x * s); } - if raw.uvlock && raw.x > 0.0 - && (processed_face.facing != Direction::Up && processed_face.facing != Direction::Down) { + if raw.uvlock + && raw.x > 0.0 + && (processed_face.facing != Direction::Up + && processed_face.facing != Direction::Down) + { let rot_x = (raw.x * (::std::f64::consts::PI / 180.0)) as f32; let c = rot_x.cos() as i16; let s = rot_x.sin() as i16; - let x = v.toffsetx - 8*tw; - let y = v.toffsety - 8*th; - v.toffsetx = 8*tw + (x*c - y*s); - v.toffsety = 8*th + (y*c + x*s); + let x = v.toffsetx - 8 * tw; + let y = v.toffsety - 8 * th; + v.toffsetx = 8 * tw + (x * c - y * s); + v.toffsety = 8 * th + (y * c + x * s); } } @@ -713,15 +809,18 @@ const FACE_ROTATION_X: &[Direction] = &[ Direction::Up, ]; -fn rotate_direction(val: Direction, offset: i32, rots: &[Direction], invalid: &[Direction]) -> Direction { +fn rotate_direction( + val: Direction, + offset: i32, + rots: &[Direction], + invalid: &[Direction], +) -> Direction { for d in invalid { if *d == val { return val; } } - let pos = rots.iter() - .position(|v| *v == val) - .unwrap_or(0) as i32; + let pos = rots.iter().position(|v| *v == val).unwrap_or(0) as i32; rots[(rots.len() as i32 + pos + offset) as usize % rots.len()] } @@ -767,7 +866,7 @@ enum BuiltinType { Generated, Entity, Compass, - Clock + Clock, } #[derive(Debug)] @@ -789,7 +888,11 @@ struct RawModel { impl RawModel { fn lookup_texture(&self, name: &str) -> String { if !name.is_empty() && name.starts_with('#') { - let tex = self.texture_vars.get(&name[1..]).cloned().unwrap_or("".to_owned()); + let tex = self + .texture_vars + .get(&name[1..]) + .cloned() + .unwrap_or("".to_owned()); return self.lookup_texture(&tex); } name.to_owned() @@ -852,7 +955,15 @@ impl Model { self.faces.extend_from_slice(&other.faces); } - fn render(&self, factory: &Factory, snapshot: &world::Snapshot, x: i32, y: i32, z: i32, buf: &mut W) -> usize { + fn render( + &self, + factory: &Factory, + snapshot: &world::Snapshot, + x: i32, + y: i32, + z: i32, + buf: &mut W, + ) -> usize { let this = snapshot.get_block(x, y, z); let this_mat = this.get_material(); let mut indices = 0; @@ -879,9 +990,19 @@ impl Model { let (mut cr, mut cg, mut cb) = if face.tint_index == 0 { match tint { TintType::Default => (255, 255, 255), - TintType::Color{r, g, b} => (r, g, b), - TintType::Grass => calculate_biome(snapshot, vert.x as i32, vert.z as i32, &factory.grass_colors), - TintType::Foliage => calculate_biome(snapshot, vert.x as i32, vert.z as i32, &factory.foliage_colors), + TintType::Color { r, g, b } => (r, g, b), + TintType::Grass => calculate_biome( + snapshot, + vert.x as i32, + vert.z as i32, + &factory.grass_colors, + ), + TintType::Foliage => calculate_biome( + snapshot, + vert.x as i32, + vert.z as i32, + &factory.foliage_colors, + ), } } else { (255, 255, 255) @@ -898,13 +1019,15 @@ impl Model { let (bl, sl) = calculate_light( snapshot, - x, y, z, + x, + y, + z, vert.x as f64, vert.y as f64, vert.z as f64, face.facing, self.ambient_occlusion, - this_mat.force_shade + this_mat.force_shade, ); vert.block_light = bl; vert.sky_light = sl; @@ -915,15 +1038,20 @@ impl Model { } } -fn calculate_biome(snapshot: &world::Snapshot, x: i32, z: i32, img: &image::DynamicImage) -> (u8, u8, u8) { - use std::cmp::{min, max}; +fn calculate_biome( + snapshot: &world::Snapshot, + x: i32, + z: i32, + img: &image::DynamicImage, +) -> (u8, u8, u8) { + use std::cmp::{max, min}; let mut count = 0; let mut r = 0; let mut g = 0; let mut b = 0; - for xx in -1 .. 2 { - for zz in -1 .. 2 { - let bi = snapshot.get_biome(x+xx, z+zz); + for xx in -1..2 { + for zz in -1..2 { + let bi = snapshot.get_biome(x + xx, z + zz); let color_index = bi.get_color_index(); let ix = color_index & 0xFF; let iy = color_index >> 8; @@ -939,13 +1067,23 @@ fn calculate_biome(snapshot: &world::Snapshot, x: i32, z: i32, img: &image::Dyna count += 1; } } - ((r/count) as u8, (g/count) as u8, (b/count) as u8) + ((r / count) as u8, (g / count) as u8, (b / count) as u8) } -fn calculate_light(snapshot: &world::Snapshot, orig_x: i32, orig_y: i32, orig_z: i32, - x: f64, y: f64, z: f64, face: Direction, smooth: bool, force: bool) -> (u16, u16) { - use std::cmp::max; +fn calculate_light( + snapshot: &world::Snapshot, + orig_x: i32, + orig_y: i32, + orig_z: i32, + x: f64, + y: f64, + z: f64, + face: Direction, + smooth: bool, + force: bool, +) -> (u16, u16) { use crate::world::block; + use std::cmp::max; let (ox, oy, oz) = face.get_offset(); let s_block_light = snapshot.get_block_light(orig_x + ox, orig_y + oy, orig_z + oz); @@ -973,8 +1111,13 @@ fn calculate_light(snapshot: &world::Snapshot, orig_x: i32, orig_y: i32, orig_z: let lz = (z + oz + dz).round() as i32; let mut bl = snapshot.get_block_light(lx, ly, lz); let mut sl = snapshot.get_sky_light(lx, ly, lz); - if (force && match snapshot.get_block(lx, ly, lz) { block::Air{} => false, _ => true }) - || (sl == 0 && bl == 0){ + if (force + && match snapshot.get_block(lx, ly, lz) { + block::Air {} => false, + _ => true, + }) + || (sl == 0 && bl == 0) + { bl = s_block_light; sl = s_sky_light; } @@ -985,43 +1128,50 @@ fn calculate_light(snapshot: &world::Snapshot, orig_x: i32, orig_y: i32, orig_z: } } - ((((block_light * 4000) / count) as u16), (((sky_light * 4000) / count) as u16)) + ( + (((block_light * 4000) / count) as u16), + (((sky_light * 4000) / count) as u16), + ) } - - pub const PRECOMPUTED_VERTS: [&[BlockVertex; 4]; 6] = [ - &[ // Up + &[ + // Up BlockVertex::base(0.0, 1.0, 0.0, 0, 0), BlockVertex::base(1.0, 1.0, 0.0, 1, 0), BlockVertex::base(0.0, 1.0, 1.0, 0, 1), BlockVertex::base(1.0, 1.0, 1.0, 1, 1), ], - &[ // Down + &[ + // Down BlockVertex::base(0.0, 0.0, 0.0, 0, 1), BlockVertex::base(0.0, 0.0, 1.0, 0, 0), BlockVertex::base(1.0, 0.0, 0.0, 1, 1), BlockVertex::base(1.0, 0.0, 1.0, 1, 0), ], - &[ // North + &[ + // North BlockVertex::base(0.0, 0.0, 0.0, 1, 1), BlockVertex::base(1.0, 0.0, 0.0, 0, 1), BlockVertex::base(0.0, 1.0, 0.0, 1, 0), BlockVertex::base(1.0, 1.0, 0.0, 0, 0), ], - &[ // South + &[ + // South BlockVertex::base(0.0, 0.0, 1.0, 0, 1), BlockVertex::base(0.0, 1.0, 1.0, 0, 0), BlockVertex::base(1.0, 0.0, 1.0, 1, 1), BlockVertex::base(1.0, 1.0, 1.0, 1, 0), ], - &[ // West + &[ + // West BlockVertex::base(0.0, 0.0, 0.0, 0, 1), BlockVertex::base(0.0, 1.0, 0.0, 0, 0), BlockVertex::base(0.0, 0.0, 1.0, 1, 1), BlockVertex::base(0.0, 1.0, 1.0, 1, 0), ], - &[ // East + &[ + // East BlockVertex::base(1.0, 0.0, 0.0, 1, 1), BlockVertex::base(1.0, 0.0, 1.0, 0, 1), BlockVertex::base(1.0, 1.0, 0.0, 1, 0), @@ -1051,11 +1201,21 @@ pub struct BlockVertex { impl BlockVertex { const fn base(x: f32, y: f32, z: f32, tx: i16, ty: i16) -> BlockVertex { BlockVertex { - x, y, z, - tx: 0, ty: 0, tw: 0, th: 0, - toffsetx: tx, toffsety: ty, tatlas: 0, - r: 0, g: 0, b: 0, - block_light: 0, sky_light: 0, + x, + y, + z, + tx: 0, + ty: 0, + tw: 0, + th: 0, + toffsetx: tx, + toffsety: ty, + tatlas: 0, + r: 0, + g: 0, + b: 0, + block_light: 0, + sky_light: 0, } } pub fn write(&self, w: &mut W) { diff --git a/src/render/atlas.rs b/src/render/atlas.rs index abc47f7..8ad527e 100644 --- a/src/render/atlas.rs +++ b/src/render/atlas.rs @@ -26,7 +26,9 @@ pub struct Rect { impl Atlas { pub fn new(width: usize, height: usize) -> Atlas { - let mut a = Atlas { free_space: Vec::new() }; + let mut a = Atlas { + free_space: Vec::new(), + }; a.free_space.push(Rect { x: 0, y: 0, @@ -78,13 +80,15 @@ impl Atlas { } else { if t.height > height { // Split by height - self.free_space.insert(0, - Rect { - x: t.x, - y: t.y + height, - width, - height: t.height - height, - }); + self.free_space.insert( + 0, + Rect { + x: t.x, + y: t.y + height, + width, + height: t.height - height, + }, + ); target_index += 1; } t.x += width; diff --git a/src/render/clouds.rs b/src/render/clouds.rs index 420a5cd..c3d102f 100644 --- a/src/render/clouds.rs +++ b/src/render/clouds.rs @@ -1,10 +1,9 @@ - use std::sync::{Arc, RwLock}; -use cgmath::{Point3, Matrix4}; -use byteorder::{WriteBytesExt, NativeEndian}; -use crate::gl; use super::glsl; +use crate::gl; +use byteorder::{NativeEndian, WriteBytesExt}; +use cgmath::{Matrix4, Point3}; use log::error; pub struct Clouds { @@ -115,8 +114,8 @@ impl Clouds { let mut data = vec![]; let mut num_points = 0; - for x in -160 .. 160 { - for z in -160 .. 160 { + for x in -160..160 { + for z in -160..160 { let _ = data.write_f32::(x as f32); let _ = data.write_f32::(128.0); let _ = data.write_f32::(z as f32); @@ -126,11 +125,19 @@ impl Clouds { buffer.set_data(gl::ARRAY_BUFFER, &data, gl::STATIC_DRAW); - let heightmap_data = vec![0; 512*512]; + let heightmap_data = vec![0; 512 * 512]; let texture = gl::Texture::new(); texture.bind(gl::TEXTURE_2D); - texture.image_2d(gl::TEXTURE_2D, 0, 512, 512, gl::RED, gl::UNSIGNED_BYTE, Some(&heightmap_data)); + texture.image_2d( + gl::TEXTURE_2D, + 0, + 512, + 512, + gl::RED, + gl::UNSIGNED_BYTE, + Some(&heightmap_data), + ); texture.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::NEAREST); texture.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::NEAREST); @@ -163,7 +170,15 @@ impl Clouds { } } - pub fn draw(&mut self, camera_pos: &Point3, perspective_matrix: &Matrix4, camera_matrix: &Matrix4, light_level: f32, sky_offset: f32, delta: f64) { + pub fn draw( + &mut self, + camera_pos: &Point3, + perspective_matrix: &Matrix4, + camera_matrix: &Matrix4, + light_level: f32, + sky_offset: f32, + delta: f64, + ) { self.offset += delta; let tex = super::Renderer::get_texture(&self.textures, "steven:environment/clouds"); @@ -173,12 +188,16 @@ impl Clouds { self.u_camera_matrix.set_matrix4(camera_matrix); self.u_sky_offset.set_float(sky_offset); self.u_light_level.set_float(light_level); - self.u_offset.set_float3(camera_pos.x.floor() as f32, 0.0, camera_pos.z.floor() as f32); + self.u_offset.set_float3( + camera_pos.x.floor() as f32, + 0.0, + camera_pos.z.floor() as f32, + ); self.u_texture_info.set_float4( tex.get_x() as f32, tex.get_y() as f32, tex.get_width() as f32, - tex.get_height() as f32 + tex.get_height() as f32, ); self.u_atlas.set_float(tex.atlas as f32); self.u_cloud_offset.set_float((self.offset / 60.0) as f32); @@ -187,7 +206,17 @@ impl Clouds { gl::active_texture(1); self.texture.bind(gl::TEXTURE_2D); if self.dirty { - self.texture.sub_image_2d(gl::TEXTURE_2D, 0, 0, 0, 512, 512, gl::RED, gl::UNSIGNED_BYTE, &self.heightmap_data); + self.texture.sub_image_2d( + gl::TEXTURE_2D, + 0, + 0, + 0, + 512, + 512, + gl::RED, + gl::UNSIGNED_BYTE, + &self.heightmap_data, + ); self.dirty = false; } self.u_cloud_map.set_int(1); diff --git a/src/render/glsl.rs b/src/render/glsl.rs index 28cfcf7..65aa8ff 100644 --- a/src/render/glsl.rs +++ b/src/render/glsl.rs @@ -20,13 +20,16 @@ pub struct Registry { } impl Registry { - pub fn new() -> Registry { Default::default() } + pub fn new() -> Registry { + Default::default() + } pub fn register(&mut self, name: &str, source: &str) { if self.shaders.contains_key(name) { panic!("shader {} is already defined", name); } - self.shaders.insert(name.to_owned(), source.trim().to_owned()); + self.shaders + .insert(name.to_owned(), source.trim().to_owned()); } pub fn get(&self, name: &str) -> String { diff --git a/src/render/mod.rs b/src/render/mod.rs index 00c52e2..d70f667 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -16,29 +16,29 @@ mod atlas; pub mod glsl; #[macro_use] pub mod shaders; -pub mod ui; -pub mod model; pub mod clouds; +pub mod model; +pub mod ui; -use std::collections::HashMap; -use std::sync::{Arc, RwLock}; -use std::io::Write; -use crate::resources; use crate::gl; +use crate::resources; +use crate::world; +use byteorder::{NativeEndian, WriteBytesExt}; +use cgmath::prelude::*; +use collision; use image; use image::{GenericImage, GenericImageView}; -use byteorder::{WriteBytesExt, NativeEndian}; -use serde_json; -use cgmath::prelude::*; -use crate::world; -use collision; use log::{error, trace}; +use serde_json; +use std::collections::HashMap; +use std::io::Write; +use std::sync::{Arc, RwLock}; -use std::hash::BuildHasherDefault; use crate::types::hash::FNVHash; +use std::hash::BuildHasherDefault; use std::sync::atomic::{AtomicIsize, Ordering}; -use std::thread; use std::sync::mpsc; +use std::thread; #[cfg(not(target_arch = "wasm32"))] use reqwest; @@ -100,7 +100,9 @@ pub struct ChunkBuffer { } impl ChunkBuffer { - pub fn new() -> ChunkBuffer { Default::default() } + pub fn new() -> ChunkBuffer { + Default::default() + } } struct ChunkRenderInfo { @@ -156,19 +158,19 @@ init_shader! { impl Renderer { pub fn new(res: Arc>) -> Renderer { - let version = { - res.read().unwrap().version() - }; + let version = { res.read().unwrap().version() }; let tex = gl::Texture::new(); tex.bind(gl::TEXTURE_2D_ARRAY); - tex.image_3d(gl::TEXTURE_2D_ARRAY, - 0, - ATLAS_SIZE as u32, - ATLAS_SIZE as u32, - 1, - gl::RGBA, - gl::UNSIGNED_BYTE, - &[0; ATLAS_SIZE * ATLAS_SIZE * 4]); + tex.image_3d( + gl::TEXTURE_2D_ARRAY, + 0, + ATLAS_SIZE as u32, + ATLAS_SIZE as u32, + 1, + gl::RGBA, + gl::UNSIGNED_BYTE, + &[0; ATLAS_SIZE * ATLAS_SIZE * 4], + ); tex.set_parameter(gl::TEXTURE_2D_ARRAY, gl::TEXTURE_MAG_FILTER, gl::NEAREST); tex.set_parameter(gl::TEXTURE_2D_ARRAY, gl::TEXTURE_MIN_FILTER, gl::NEAREST); tex.set_parameter(gl::TEXTURE_2D_ARRAY, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE); @@ -248,9 +250,13 @@ impl Renderer { if rm.version() != self.resource_version { self.resource_version = rm.version(); trace!("Updating textures to {}", self.resource_version); - self.textures.write().unwrap().update_textures(self.resource_version); + self.textures + .write() + .unwrap() + .update_textures(self.resource_version); - self.model.rebuild_models(self.resource_version, &self.textures); + self.model + .rebuild_models(self.resource_version, &self.textures); } } @@ -262,34 +268,47 @@ impl Renderer { let fovy = cgmath::Rad::from(cgmath::Deg(90.0_f32)); let aspect = (width as f32 / height as f32).max(1.0); - self.perspective_matrix = cgmath::Matrix4::from( - cgmath::PerspectiveFov { - fovy, - aspect, - near: 0.1f32, - far: 500.0f32, - } - ); + self.perspective_matrix = cgmath::Matrix4::from(cgmath::PerspectiveFov { + fovy, + aspect, + near: 0.1f32, + far: 500.0f32, + }); self.init_trans(width, height); } self.view_vector = cgmath::Vector3::new( - ((self.camera.yaw - PI64/2.0).cos() * -self.camera.pitch.cos()) as f32, + ((self.camera.yaw - PI64 / 2.0).cos() * -self.camera.pitch.cos()) as f32, (-self.camera.pitch.sin()) as f32, - (-(self.camera.yaw - PI64/2.0).sin() * -self.camera.pitch.cos()) as f32 + (-(self.camera.yaw - PI64 / 2.0).sin() * -self.camera.pitch.cos()) as f32, + ); + let camera = cgmath::Point3::new( + -self.camera.pos.x as f32, + -self.camera.pos.y as f32, + self.camera.pos.z as f32, ); - let camera = cgmath::Point3::new(-self.camera.pos.x as f32, -self.camera.pos.y as f32, self.camera.pos.z as f32); let camera_matrix = cgmath::Matrix4::look_at( camera, - camera + cgmath::Point3::new(-self.view_vector.x, -self.view_vector.y, self.view_vector.z).to_vec(), - cgmath::Vector3::new(0.0, -1.0, 0.0) + camera + + cgmath::Point3::new(-self.view_vector.x, -self.view_vector.y, self.view_vector.z) + .to_vec(), + cgmath::Vector3::new(0.0, -1.0, 0.0), ); self.camera_matrix = camera_matrix * cgmath::Matrix4::from_nonuniform_scale(-1.0, 1.0, 1.0); - self.frustum = collision::Frustum::from_matrix4(self.perspective_matrix * self.camera_matrix).unwrap(); + self.frustum = + collision::Frustum::from_matrix4(self.perspective_matrix * self.camera_matrix).unwrap(); } - pub fn tick(&mut self, world: &mut world::World, delta: f64, width: u32, height: u32, physical_width: u32, physical_height: u32) { + pub fn tick( + &mut self, + world: &mut world::World, + delta: f64, + width: u32, + height: u32, + physical_width: u32, + physical_height: u32, + ) { self.update_textures(delta); let trans = self.trans.as_mut().unwrap(); @@ -302,18 +321,22 @@ impl Renderer { let time_offset = self.sky_offset * 0.9; gl::clear_color( - (122.0 / 255.0) * time_offset, - (165.0 / 255.0) * time_offset, - (247.0 / 255.0) * time_offset, - 1.0 + (122.0 / 255.0) * time_offset, + (165.0 / 255.0) * time_offset, + (247.0 / 255.0) * time_offset, + 1.0, ); gl::clear(gl::ClearFlags::Color | gl::ClearFlags::Depth); // Chunk rendering self.chunk_shader.program.use_program(); - self.chunk_shader.perspective_matrix.set_matrix4(&self.perspective_matrix); - self.chunk_shader.camera_matrix.set_matrix4(&self.camera_matrix); + self.chunk_shader + .perspective_matrix + .set_matrix4(&self.perspective_matrix); + self.chunk_shader + .camera_matrix + .set_matrix4(&self.camera_matrix); self.chunk_shader.texture.set_int(0); self.chunk_shader.light_level.set_float(self.light_level); self.chunk_shader.sky_offset.set_float(self.sky_offset); @@ -321,36 +344,71 @@ impl Renderer { for (pos, info) in world.get_render_list() { if let Some(solid) = info.solid.as_ref() { if solid.count > 0 { - self.chunk_shader.offset.set_int3(pos.0, pos.1 * 4096, pos.2); + self.chunk_shader + .offset + .set_int3(pos.0, pos.1 * 4096, pos.2); solid.array.bind(); - gl::draw_elements(gl::TRIANGLES, solid.count as i32, self.element_buffer_type, 0); + gl::draw_elements( + gl::TRIANGLES, + solid.count as i32, + self.element_buffer_type, + 0, + ); } } } // Line rendering // Model rendering - self.model.draw(&self.frustum, &self.perspective_matrix, &self.camera_matrix, self.light_level, self.sky_offset); + self.model.draw( + &self.frustum, + &self.perspective_matrix, + &self.camera_matrix, + self.light_level, + self.sky_offset, + ); if world.copy_cloud_heightmap(&mut self.clouds.heightmap_data) { self.clouds.dirty = true; } - self.clouds.draw(&self.camera.pos, &self.perspective_matrix, &self.camera_matrix, self.light_level, self.sky_offset, delta); + self.clouds.draw( + &self.camera.pos, + &self.perspective_matrix, + &self.camera_matrix, + self.light_level, + self.sky_offset, + delta, + ); // Trans chunk rendering self.chunk_shader_alpha.program.use_program(); - self.chunk_shader_alpha.perspective_matrix.set_matrix4(&self.perspective_matrix); - self.chunk_shader_alpha.camera_matrix.set_matrix4(&self.camera_matrix); + self.chunk_shader_alpha + .perspective_matrix + .set_matrix4(&self.perspective_matrix); + self.chunk_shader_alpha + .camera_matrix + .set_matrix4(&self.camera_matrix); self.chunk_shader_alpha.texture.set_int(0); - self.chunk_shader_alpha.light_level.set_float(self.light_level); - self.chunk_shader_alpha.sky_offset.set_float(self.sky_offset); + self.chunk_shader_alpha + .light_level + .set_float(self.light_level); + self.chunk_shader_alpha + .sky_offset + .set_float(self.sky_offset); // Copy the depth buffer trans.main.bind_read(); trans.trans.bind_draw(); gl::blit_framebuffer( - 0, 0, physical_width as i32, physical_height as i32, - 0, 0, physical_width as i32, physical_height as i32, - gl::ClearFlags::Depth, gl::NEAREST + 0, + 0, + physical_width as i32, + physical_height as i32, + 0, + 0, + physical_width as i32, + physical_height as i32, + gl::ClearFlags::Depth, + gl::NEAREST, ); gl::enable(gl::BLEND); @@ -360,14 +418,26 @@ impl Renderer { gl::clear(gl::ClearFlags::Color); gl::clear_buffer(gl::COLOR, 0, &[0.0, 0.0, 0.0, 1.0]); gl::clear_buffer(gl::COLOR, 1, &[0.0, 0.0, 0.0, 0.0]); - gl::blend_func_separate(gl::ONE_FACTOR, gl::ONE_FACTOR, gl::ZERO_FACTOR, gl::ONE_MINUS_SRC_ALPHA); + gl::blend_func_separate( + gl::ONE_FACTOR, + gl::ONE_FACTOR, + gl::ZERO_FACTOR, + gl::ONE_MINUS_SRC_ALPHA, + ); for (pos, info) in world.get_render_list().iter().rev() { if let Some(trans) = info.trans.as_ref() { if trans.count > 0 { - self.chunk_shader_alpha.offset.set_int3(pos.0, pos.1 * 4096, pos.2); + self.chunk_shader_alpha + .offset + .set_int3(pos.0, pos.1 * 4096, pos.2); trans.array.bind(); - gl::draw_elements(gl::TRIANGLES, trans.count as i32, self.element_buffer_type, 0); + gl::draw_elements( + gl::TRIANGLES, + trans.count as i32, + self.element_buffer_type, + 0, + ); } } } @@ -396,7 +466,8 @@ impl Renderer { let (data, ty) = self::generate_element_buffer(size); self.element_buffer_type = ty; self.element_buffer.bind(gl::ELEMENT_ARRAY_BUFFER); - self.element_buffer.set_data(gl::ELEMENT_ARRAY_BUFFER, &data, gl::DYNAMIC_DRAW); + self.element_buffer + .set_data(gl::ELEMENT_ARRAY_BUFFER, &data, gl::DYNAMIC_DRAW); self.element_buffer_size = size; } } @@ -432,16 +503,27 @@ impl Renderer { info.buffer.bind(gl::ARRAY_BUFFER); if new || info.buffer_size < data.len() { info.buffer_size = data.len(); - info.buffer.set_data(gl::ARRAY_BUFFER, data, gl::DYNAMIC_DRAW); + info.buffer + .set_data(gl::ARRAY_BUFFER, data, gl::DYNAMIC_DRAW); } else { info.buffer.re_set_data(gl::ARRAY_BUFFER, data); } - self.chunk_shader.position.vertex_pointer(3, gl::FLOAT, false, 40, 0); - self.chunk_shader.texture_info.vertex_pointer(4, gl::UNSIGNED_SHORT, false, 40, 12); - self.chunk_shader.texture_offset.vertex_pointer(3, gl::SHORT, false, 40, 20); - self.chunk_shader.color.vertex_pointer(3, gl::UNSIGNED_BYTE, true, 40, 28); - self.chunk_shader.lighting.vertex_pointer(2, gl::UNSIGNED_SHORT, false, 40, 32); + self.chunk_shader + .position + .vertex_pointer(3, gl::FLOAT, false, 40, 0); + self.chunk_shader + .texture_info + .vertex_pointer(4, gl::UNSIGNED_SHORT, false, 40, 12); + self.chunk_shader + .texture_offset + .vertex_pointer(3, gl::SHORT, false, 40, 20); + self.chunk_shader + .color + .vertex_pointer(3, gl::UNSIGNED_BYTE, true, 40, 28); + self.chunk_shader + .lighting + .vertex_pointer(2, gl::UNSIGNED_SHORT, false, 40, 32); info.count = count; } @@ -477,16 +559,27 @@ impl Renderer { info.buffer.bind(gl::ARRAY_BUFFER); if new || info.buffer_size < data.len() { info.buffer_size = data.len(); - info.buffer.set_data(gl::ARRAY_BUFFER, data, gl::DYNAMIC_DRAW); + info.buffer + .set_data(gl::ARRAY_BUFFER, data, gl::DYNAMIC_DRAW); } else { info.buffer.re_set_data(gl::ARRAY_BUFFER, data); } - self.chunk_shader_alpha.position.vertex_pointer(3, gl::FLOAT, false, 40, 0); - self.chunk_shader_alpha.texture_info.vertex_pointer(4, gl::UNSIGNED_SHORT, false, 40, 12); - self.chunk_shader_alpha.texture_offset.vertex_pointer(3, gl::SHORT, false, 40, 20); - self.chunk_shader_alpha.color.vertex_pointer(3, gl::UNSIGNED_BYTE, true, 40, 28); - self.chunk_shader_alpha.lighting.vertex_pointer(2, gl::UNSIGNED_SHORT, false, 40, 32); + self.chunk_shader_alpha + .position + .vertex_pointer(3, gl::FLOAT, false, 40, 0); + self.chunk_shader_alpha + .texture_info + .vertex_pointer(4, gl::UNSIGNED_SHORT, false, 40, 12); + self.chunk_shader_alpha + .texture_offset + .vertex_pointer(3, gl::SHORT, false, 40, 20); + self.chunk_shader_alpha + .color + .vertex_pointer(3, gl::UNSIGNED_BYTE, true, 40, 28); + self.chunk_shader_alpha + .lighting + .vertex_pointer(2, gl::UNSIGNED_SHORT, false, 40, 32); info.count = count; } @@ -501,19 +594,23 @@ impl Renderer { unsafe { data.set_len(len); } - self.gl_texture.get_pixels(gl::TEXTURE_2D_ARRAY, - 0, - gl::RGBA, - gl::UNSIGNED_BYTE, - &mut data[..]); - self.gl_texture.image_3d(gl::TEXTURE_2D_ARRAY, - 0, - ATLAS_SIZE as u32, - ATLAS_SIZE as u32, - tex.atlases.len() as u32, - gl::RGBA, - gl::UNSIGNED_BYTE, - &data[..]); + self.gl_texture.get_pixels( + gl::TEXTURE_2D_ARRAY, + 0, + gl::RGBA, + gl::UNSIGNED_BYTE, + &mut data[..], + ); + self.gl_texture.image_3d( + gl::TEXTURE_2D_ARRAY, + 0, + ATLAS_SIZE as u32, + ATLAS_SIZE as u32, + tex.atlases.len() as u32, + gl::RGBA, + gl::UNSIGNED_BYTE, + &data[..], + ); self.texture_layers = tex.atlases.len(); } tex.pending_uploads.len() @@ -525,17 +622,19 @@ impl Renderer { let atlas = upload.0; let rect = upload.1; let img = &upload.2; - self.gl_texture.sub_image_3d(gl::TEXTURE_2D_ARRAY, - 0, - rect.x as u32, - rect.y as u32, - atlas as u32, - rect.width as u32, - rect.height as u32, - 1, - gl::RGBA, - gl::UNSIGNED_BYTE, - &img[..]); + self.gl_texture.sub_image_3d( + gl::TEXTURE_2D_ARRAY, + 0, + rect.x as u32, + rect.y as u32, + atlas as u32, + rect.width as u32, + rect.height as u32, + 1, + gl::RGBA, + gl::UNSIGNED_BYTE, + &img[..], + ); } tex.pending_uploads.clear(); } @@ -567,30 +666,36 @@ impl Renderer { if ani.remaining_time <= 0.0 { ani.current_frame = (ani.current_frame + 1) % ani.frames.len(); ani.remaining_time += ani.frames[ani.current_frame].time as f64; - let offset = ani.texture.width * ani.texture.width * - ani.frames[ani.current_frame].index * 4; + let offset = + ani.texture.width * ani.texture.width * ani.frames[ani.current_frame].index * 4; let offset2 = offset + ani.texture.width * ani.texture.width * 4; - self.gl_texture.sub_image_3d(gl::TEXTURE_2D_ARRAY, - 0, - ani.texture.get_x() as u32, - ani.texture.get_y() as u32, - ani.texture.atlas as u32, - ani.texture.get_width() as u32, - ani.texture.get_height() as u32, - 1, - gl::RGBA, - gl::UNSIGNED_BYTE, - &ani.data[offset..offset2]); + self.gl_texture.sub_image_3d( + gl::TEXTURE_2D_ARRAY, + 0, + ani.texture.get_x() as u32, + ani.texture.get_y() as u32, + ani.texture.atlas as u32, + ani.texture.get_width() as u32, + ani.texture.get_height() as u32, + 1, + gl::RGBA, + gl::UNSIGNED_BYTE, + &ani.data[offset..offset2], + ); } else { ani.remaining_time -= delta / 3.0; } } - } fn init_trans(&mut self, width: u32, height: u32) { self.trans = None; - self.trans = Some(TransInfo::new(width, height, &self.chunk_shader_alpha, &self.trans_shader)); + self.trans = Some(TransInfo::new( + width, + height, + &self.chunk_shader_alpha, + &self.trans_shader, + )); } pub fn get_textures(&self) -> Arc> { @@ -616,9 +721,7 @@ impl Renderer { } pub fn get_texture(textures: &RwLock, name: &str) -> Texture { - let tex = { - textures.read().unwrap().get_texture(name) - }; + let tex = { textures.read().unwrap().get_texture(name) }; match tex { Some(val) => val, None => { @@ -636,9 +739,7 @@ impl Renderer { } pub fn get_skin(&self, textures: &RwLock, url: &str) -> Texture { - let tex = { - textures.read().unwrap().get_skin(url) - }; + let tex = { textures.read().unwrap().get_skin(url) }; match tex { Some(val) => val, None => { @@ -686,27 +787,59 @@ init_shader! { } impl TransInfo { - pub fn new(width: u32, height: u32, chunk_shader: &ChunkShaderAlpha, shader: &TransShader) -> TransInfo { + pub fn new( + width: u32, + height: u32, + chunk_shader: &ChunkShaderAlpha, + shader: &TransShader, + ) -> TransInfo { let trans = gl::Framebuffer::new(); trans.bind(); let accum = gl::Texture::new(); accum.bind(gl::TEXTURE_2D); - accum.image_2d_ex(gl::TEXTURE_2D, 0, width, height, gl::RGBA16F, gl::RGBA, gl::FLOAT, None); + accum.image_2d_ex( + gl::TEXTURE_2D, + 0, + width, + height, + gl::RGBA16F, + gl::RGBA, + gl::FLOAT, + None, + ); accum.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR); accum.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAX_LEVEL, gl::LINEAR); trans.texture_2d(gl::COLOR_ATTACHMENT_0, gl::TEXTURE_2D, &accum, 0); let revealage = gl::Texture::new(); revealage.bind(gl::TEXTURE_2D); - revealage.image_2d_ex(gl::TEXTURE_2D, 0, width, height, gl::R16F, gl::RED, gl::FLOAT, None); + revealage.image_2d_ex( + gl::TEXTURE_2D, + 0, + width, + height, + gl::R16F, + gl::RED, + gl::FLOAT, + None, + ); revealage.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR); revealage.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAX_LEVEL, gl::LINEAR); trans.texture_2d(gl::COLOR_ATTACHMENT_1, gl::TEXTURE_2D, &revealage, 0); let trans_depth = gl::Texture::new(); trans_depth.bind(gl::TEXTURE_2D); - trans_depth.image_2d_ex(gl::TEXTURE_2D, 0, width, height, gl::DEPTH_COMPONENT24, gl::DEPTH_COMPONENT, gl::UNSIGNED_BYTE, None); + trans_depth.image_2d_ex( + gl::TEXTURE_2D, + 0, + width, + height, + gl::DEPTH_COMPONENT24, + gl::DEPTH_COMPONENT, + gl::UNSIGNED_BYTE, + None, + ); trans_depth.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR); trans_depth.set_parameter(gl::TEXTURE_2D, gl::TEXTURE_MAX_LEVEL, gl::LINEAR); trans.texture_2d(gl::DEPTH_ATTACHMENT, gl::TEXTURE_2D, &trans_depth, 0); @@ -722,13 +855,37 @@ impl TransInfo { let fb_color = gl::Texture::new(); fb_color.bind(gl::TEXTURE_2D_MULTISAMPLE); - fb_color.image_2d_sample(gl::TEXTURE_2D_MULTISAMPLE, NUM_SAMPLES, width, height, gl::RGBA8, false); - main.texture_2d(gl::COLOR_ATTACHMENT_0, gl::TEXTURE_2D_MULTISAMPLE, &fb_color, 0); + fb_color.image_2d_sample( + gl::TEXTURE_2D_MULTISAMPLE, + NUM_SAMPLES, + width, + height, + gl::RGBA8, + false, + ); + main.texture_2d( + gl::COLOR_ATTACHMENT_0, + gl::TEXTURE_2D_MULTISAMPLE, + &fb_color, + 0, + ); let fb_depth = gl::Texture::new(); fb_depth.bind(gl::TEXTURE_2D_MULTISAMPLE); - fb_depth.image_2d_sample(gl::TEXTURE_2D_MULTISAMPLE, NUM_SAMPLES, width, height, gl::DEPTH_COMPONENT24, false); - main.texture_2d(gl::DEPTH_ATTACHMENT, gl::TEXTURE_2D_MULTISAMPLE, &fb_depth, 0); + fb_depth.image_2d_sample( + gl::TEXTURE_2D_MULTISAMPLE, + NUM_SAMPLES, + width, + height, + gl::DEPTH_COMPONENT24, + false, + ); + main.texture_2d( + gl::DEPTH_ATTACHMENT, + gl::TEXTURE_2D_MULTISAMPLE, + &fb_depth, + 0, + ); gl::check_framebuffer_status(); gl::unbind_framebuffer(); @@ -740,7 +897,11 @@ impl TransInfo { buffer.bind(gl::ARRAY_BUFFER); let mut data = vec![]; - for f in [-1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0].iter() { + for f in [ + -1.0, 1.0, 1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, + ] + .iter() + { data.write_f32::(*f).unwrap(); } buffer.set_data(gl::ARRAY_BUFFER, &data, gl::STATIC_DRAW); @@ -798,7 +959,13 @@ pub struct TextureManager { } impl TextureManager { - fn new(res: Arc>) -> (TextureManager, mpsc::Sender, mpsc::Receiver<(String, Option)>) { + fn new( + res: Arc>, + ) -> ( + TextureManager, + mpsc::Sender, + mpsc::Receiver<(String, Option)>, + ) { let (tx, rx) = mpsc::channel(); let (stx, srx) = mpsc::channel(); let skin_thread = thread::spawn(|| Self::process_skins(srx, tx)); @@ -824,31 +991,30 @@ impl TextureManager { } fn add_defaults(&mut self) { - self.put_texture("steven", - "missing_texture", - 2, - 2, - vec![ - 0, 0, 0, 255, - 255, 0, 255, 255, - 255, 0, 255, 255, - 0, 0, 0, 255, - ]); - self.put_texture("steven", - "solid", - 1, - 1, - vec![ - 255, 255, 255, 255, - ]); + self.put_texture( + "steven", + "missing_texture", + 2, + 2, + vec![ + 0, 0, 0, 255, 255, 0, 255, 255, 255, 0, 255, 255, 0, 0, 0, 255, + ], + ); + self.put_texture("steven", "solid", 1, 1, vec![255, 255, 255, 255]); } #[cfg(target_arch = "wasm32")] - fn process_skins(recv: mpsc::Receiver, reply: mpsc::Sender<(String, Option)>) { + fn process_skins( + recv: mpsc::Receiver, + reply: mpsc::Sender<(String, Option)>, + ) { } #[cfg(not(target_arch = "wasm32"))] - fn process_skins(recv: mpsc::Receiver, reply: mpsc::Sender<(String, Option)>) { + fn process_skins( + recv: mpsc::Receiver, + reply: mpsc::Sender<(String, Option)>, + ) { let client = reqwest::blocking::Client::new(); loop { let hash = match recv.recv() { @@ -858,21 +1024,24 @@ impl TextureManager { match Self::obtain_skin(&client, &hash) { Ok(img) => { let _ = reply.send((hash, Some(img))); - }, + } Err(err) => { error!("Failed to get skin {:?}: {}", hash, err); let _ = reply.send((hash, None)); - }, + } } } } #[cfg(not(target_arch = "wasm32"))] - fn obtain_skin(client: &::reqwest::blocking::Client, hash: &str) -> Result { + fn obtain_skin( + client: &::reqwest::blocking::Client, + hash: &str, + ) -> Result { use std::io::Read; - use std_or_web::fs; - use std::path::Path; use std::io::{Error, ErrorKind}; + use std::path::Path; + use std_or_web::fs; let path = format!("skin-cache/{}/{}.png", &hash[..2], hash); let cache_path = Path::new(&path); fs::create_dir_all(cache_path.parent().unwrap())?; @@ -892,7 +1061,7 @@ impl TextureManager { }; let mut buf = vec![]; match res.read_to_end(&mut buf) { - Ok(_) => {}, + Ok(_) => {} Err(err) => { // TODO: different error for failure to read? return Err(Error::new(ErrorKind::InvalidData, err)); @@ -913,10 +1082,11 @@ impl TextureManager { if height == 32 { // Needs changing to the new format let mut new = image::DynamicImage::new_rgba8(64, 64); - new.copy_from(&img, 0, 0).expect("Invalid png image in skin"); - for xx in 0 .. 4 { - for yy in 0 .. 16 { - for section in 0 .. 4 { + new.copy_from(&img, 0, 0) + .expect("Invalid png image in skin"); + for xx in 0..4 { + for yy in 0..16 { + for section in 0..4 { let os = match section { 0 => 2, 1 => 1, @@ -924,8 +1094,16 @@ impl TextureManager { 3 => 3, _ => unreachable!(), }; - new.put_pixel(16 + (3 - xx) + section * 4, 48 + yy, img.get_pixel(xx + os * 4, 16 + yy)); - new.put_pixel(32 + (3 - xx) + section * 4, 48 + yy, img.get_pixel(xx + 40 + os * 4, 16 + yy)); + new.put_pixel( + 16 + (3 - xx) + section * 4, + 48 + yy, + img.get_pixel(xx + os * 4, 16 + yy), + ); + new.put_pixel( + 32 + (3 - xx) + section * 4, + 48 + yy, + img.get_pixel(xx + 40 + os * 4, 16 + yy), + ); } } } @@ -942,8 +1120,8 @@ impl TextureManager { (40, 16, 16, 16), ]; for bl in blacklist.iter() { - for x in bl.0 .. (bl.0 + bl.2) { - for y in bl.1 .. (bl.1 + bl.3) { + for x in bl.0..(bl.0 + bl.2) { + for y in bl.1..(bl.1 + bl.3) { let mut col = img.get_pixel(x, y); col.0[3] = 255; img.put_pixel(x, y, col); @@ -977,7 +1155,8 @@ impl TextureManager { let (width, height) = img.dimensions(); (width, height, img.to_rgba().into_vec()) }; - let new_tex = self.put_texture("steven-dynamic", n, width as u32, height as u32, data); + let new_tex = + self.put_texture("steven-dynamic", n, width as u32, height as u32, data); self.dynamic_textures.get_mut(n).unwrap().0 = new_tex; } else if !self.textures.contains_key(name) { self.load_texture(name); @@ -1005,7 +1184,11 @@ impl TextureManager { let res = self.resources.clone(); // TODO: This shouldn't be hardcoded to steve but instead // have a way to select alex as a default. - let img = if let Some(mut val) = res.read().unwrap().open("minecraft", "textures/entity/steve.png") { + let img = if let Some(mut val) = res + .read() + .unwrap() + .open("minecraft", "textures/entity/steve.png") + { let mut data = Vec::new(); val.read_to_end(&mut data).unwrap(); image::load_from_memory(&data).unwrap() @@ -1018,7 +1201,9 @@ impl TextureManager { } fn update_skin(&mut self, hash: String, img: image::DynamicImage) { - if !self.skins.contains_key(&hash) { return; } + if !self.skins.contains_key(&hash) { + return; + } let name = format!("steven-dynamic:skin-{}", hash); let tex = self.get_texture(&name).unwrap(); let rect = atlas::Rect { @@ -1028,8 +1213,12 @@ impl TextureManager { height: tex.height, }; - self.pending_uploads.push((tex.atlas, rect, img.to_rgba().into_vec())); - self.dynamic_textures.get_mut(&format!("skin-{}", hash)).unwrap().1 = img; + self.pending_uploads + .push((tex.atlas, rect, img.to_rgba().into_vec())); + self.dynamic_textures + .get_mut(&format!("skin-{}", hash)) + .unwrap() + .1 = img; } fn get_texture(&self, name: &str) -> Option { @@ -1070,23 +1259,27 @@ impl TextureManager { self.insert_texture_dummy(plugin, name); } - fn load_animation(&mut self, - plugin: &str, - name: &str, - img: &image::DynamicImage, - data: Vec) - -> Option { + fn load_animation( + &mut self, + plugin: &str, + name: &str, + img: &image::DynamicImage, + data: Vec, + ) -> Option { let path = format!("textures/{}.png.mcmeta", name); let res = self.resources.clone(); if let Some(val) = res.read().unwrap().open(plugin, &path) { let meta: serde_json::Value = serde_json::from_reader(val).unwrap(); let animation = meta.get("animation").unwrap(); - let frame_time = animation.get("frametime").and_then(|v| v.as_i64()).unwrap_or(1); - let interpolate = animation.get("interpolate") - .and_then(|v| v.as_bool()) - .unwrap_or(false); - let frames = if let Some(frames) = animation.get("frames") - .and_then(|v| v.as_array()) { + let frame_time = animation + .get("frametime") + .and_then(|v| v.as_i64()) + .unwrap_or(1); + let interpolate = animation + .get("interpolate") + .and_then(|v| v.as_bool()) + .unwrap_or(false); + let frames = if let Some(frames) = animation.get("frames").and_then(|v| v.as_array()) { let mut out = Vec::with_capacity(frames.len()); for frame in frames { if let Some(index) = frame.as_i64() { @@ -1095,7 +1288,7 @@ impl TextureManager { time: frame_time, }) } else { - out.push(AnimationFrame{ + out.push(AnimationFrame { index: frame.get("index").unwrap().as_i64().unwrap() as usize, time: frame_time * frame.get("frameTime").unwrap().as_i64().unwrap(), }) @@ -1127,13 +1320,14 @@ impl TextureManager { None } - fn put_texture(&mut self, - plugin: &str, - name: &str, - width: u32, - height: u32, - data: Vec) - -> Texture { + fn put_texture( + &mut self, + plugin: &str, + name: &str, + width: u32, + height: u32, + data: Vec, + ) -> Texture { let (atlas, rect) = self.find_free(width as usize, height as usize); self.pending_uploads.push((atlas, rect, data)); @@ -1224,19 +1418,27 @@ impl TextureManager { height, }; self.pending_uploads.push((tex.atlas, rect, data)); - let mut t = tex.relative(0.0, 0.0, (width as f32) / (tex.width as f32), (height as f32) / (tex.height as f32)); + let mut t = tex.relative( + 0.0, + 0.0, + (width as f32) / (tex.width as f32), + (height as f32) / (tex.height as f32), + ); let old_name = mem::replace(&mut tex.name, format!("steven-dynamic:{}", name)); - self.dynamic_textures.insert(name.to_owned(), (tex.clone(), img)); + self.dynamic_textures + .insert(name.to_owned(), (tex.clone(), img)); // We need to rename the texture itself so that get_texture calls // work with the new name let mut old = self.textures.remove(&old_name).unwrap(); old.name = format!("steven-dynamic:{}", name); t.name = old.name.clone(); - self.textures.insert(format!("steven-dynamic:{}", name), old); + self.textures + .insert(format!("steven-dynamic:{}", name), old); t } else { let tex = self.put_texture("steven-dynamic", name, width as u32, height as u32, data); - self.dynamic_textures.insert(name.to_owned(), (tex.clone(), img)); + self.dynamic_textures + .insert(name.to_owned(), (tex.clone(), img)); tex } } diff --git a/src/render/model.rs b/src/render/model.rs index 8298da1..c4d2a30 100644 --- a/src/render/model.rs +++ b/src/render/model.rs @@ -1,17 +1,16 @@ - use super::glsl; use super::shaders; +use crate::format::{self, Component}; use crate::gl; -use cgmath::{Point3, Matrix4, SquareMatrix}; +use crate::model::BlockVertex; +use crate::shared::Direction; +use crate::types::hash::FNVHash; +use byteorder::{NativeEndian, WriteBytesExt}; +use cgmath::{Matrix4, Point3, SquareMatrix}; use collision::{self, Frustum, Sphere}; use std::collections::HashMap; use std::hash::BuildHasherDefault; use std::sync::{Arc, RwLock}; -use crate::types::hash::FNVHash; -use crate::shared::Direction; -use byteorder::{WriteBytesExt, NativeEndian}; -use crate::model::BlockVertex; -use crate::format::{self, Component}; pub struct Manager { collections: Vec, @@ -42,17 +41,25 @@ impl Manager { m.add_collection( &greg.get("model_vertex"), &greg.get("model_frag"), - gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA + gl::SRC_ALPHA, + gl::ONE_MINUS_SRC_ALPHA, ); m.add_collection( &greg.get("sun_vertex"), &greg.get("sun_frag"), - gl::SRC_ALPHA, gl::ONE_FACTOR + gl::SRC_ALPHA, + gl::ONE_FACTOR, ); m } - pub fn add_collection(&mut self, vert: &str, frag: &str, blend_s: gl::Factor, blend_d: gl::Factor) -> CollectionKey { + pub fn add_collection( + &mut self, + vert: &str, + frag: &str, + blend_s: gl::Factor, + blend_d: gl::Factor, + ) -> CollectionKey { let collection = Collection { shader: ModelShader::new_manual(vert, frag), models: HashMap::with_hasher(BuildHasherDefault::default()), @@ -84,11 +91,26 @@ impl Manager { collection.shader.texture_offset.map(|v| v.enable()); collection.shader.color.map(|v| v.enable()); collection.shader.id.map(|v| v.enable()); - collection.shader.position.map(|v| v.vertex_pointer(3, gl::FLOAT, false, 36, 0)); - collection.shader.texture_info.map(|v| v.vertex_pointer(4, gl::UNSIGNED_SHORT, false, 36, 12)); - collection.shader.texture_offset.map(|v| v.vertex_pointer_int(3, gl::SHORT, 36, 20)); - collection.shader.color.map(|v| v.vertex_pointer(4, gl::UNSIGNED_BYTE, true, 36, 28)); - collection.shader.id.map(|v| v.vertex_pointer_int(1, gl::UNSIGNED_BYTE, 36, 32)); + collection + .shader + .position + .map(|v| v.vertex_pointer(3, gl::FLOAT, false, 36, 0)); + collection + .shader + .texture_info + .map(|v| v.vertex_pointer(4, gl::UNSIGNED_SHORT, false, 36, 12)); + collection + .shader + .texture_offset + .map(|v| v.vertex_pointer_int(3, gl::SHORT, 36, 20)); + collection + .shader + .color + .map(|v| v.vertex_pointer(4, gl::UNSIGNED_BYTE, true, 36, 28)); + collection + .shader + .id + .map(|v| v.vertex_pointer_int(1, gl::UNSIGNED_BYTE, 36, 32)); let mut model = Model { // For culling only @@ -125,7 +147,8 @@ impl Manager { if self.max_index < model.count as usize { let (data, ty) = super::generate_element_buffer(model.count as usize); self.index_buffer.bind(gl::ELEMENT_ARRAY_BUFFER); - self.index_buffer.set_data(gl::ELEMENT_ARRAY_BUFFER, &data, gl::DYNAMIC_DRAW); + self.index_buffer + .set_data(gl::ELEMENT_ARRAY_BUFFER, &data, gl::DYNAMIC_DRAW); self.max_index = model.count as usize; self.index_type = ty; } @@ -156,8 +179,12 @@ impl Manager { let _ = buffer.write_u16::(vert.texture.get_y() as u16); let _ = buffer.write_u16::(vert.texture.get_width() as u16); let _ = buffer.write_u16::(vert.texture.get_height() as u16); - let _ = buffer.write_i16::(((vert.texture.get_width() as f64) * 16.0 * vert.texture_x) as i16); - let _ = buffer.write_i16::(((vert.texture.get_height() as f64) * 16.0 * vert.texture_y) as i16); + let _ = buffer.write_i16::( + ((vert.texture.get_width() as f64) * 16.0 * vert.texture_x) as i16, + ); + let _ = buffer.write_i16::( + ((vert.texture.get_height() as f64) * 16.0 * vert.texture_y) as i16, + ); let _ = buffer.write_i16::(vert.texture.atlas as i16); let _ = buffer.write_i16::(0); let _ = buffer.write_u8(vert.r); @@ -174,12 +201,18 @@ impl Manager { if buffer.len() < model.buffer_size { model.buffer.re_set_data(gl::ARRAY_BUFFER, &buffer); } else { - model.buffer.set_data(gl::ARRAY_BUFFER, &buffer, gl::DYNAMIC_DRAW); + model + .buffer + .set_data(gl::ARRAY_BUFFER, &buffer, gl::DYNAMIC_DRAW); model.buffer_size = buffer.len(); } } - pub fn rebuild_models(&mut self, version: usize, textures: &Arc>) { + pub fn rebuild_models( + &mut self, + version: usize, + textures: &Arc>, + ) { for collection in &mut self.collections { for (_, model) in &mut collection.models { for vert in &mut model.verts { @@ -200,28 +233,57 @@ impl Manager { } } - pub fn draw(&mut self, frustum: &Frustum, perspective_matrix: &Matrix4, camera_matrix: &Matrix4, light_level: f32, sky_offset: f32) { + pub fn draw( + &mut self, + frustum: &Frustum, + perspective_matrix: &Matrix4, + camera_matrix: &Matrix4, + light_level: f32, + sky_offset: f32, + ) { gl::enable(gl::BLEND); for collection in &self.collections { collection.shader.program.use_program(); - collection.shader.perspective_matrix.map(|v| v.set_matrix4(perspective_matrix)); - collection.shader.camera_matrix.map(|v| v.set_matrix4(camera_matrix)); + collection + .shader + .perspective_matrix + .map(|v| v.set_matrix4(perspective_matrix)); + collection + .shader + .camera_matrix + .map(|v| v.set_matrix4(camera_matrix)); collection.shader.texture.map(|v| v.set_int(0)); - collection.shader.sky_offset.map(|v| v.set_float(sky_offset)); - collection.shader.light_level.map(|v| v.set_float(light_level)); + collection + .shader + .sky_offset + .map(|v| v.set_float(sky_offset)); + collection + .shader + .light_level + .map(|v| v.set_float(light_level)); gl::blend_func(collection.blend_s, collection.blend_d); for model in collection.models.values() { - if model.radius > 0.0 && frustum.contains(&Sphere { - center: Point3::new(model.x, -model.y, model.z), - radius: model.radius - }) == collision::Relation::Out { + if model.radius > 0.0 + && frustum.contains(&Sphere { + center: Point3::new(model.x, -model.y, model.z), + radius: model.radius, + }) == collision::Relation::Out + { continue; } model.array.bind(); - collection.shader.lighting.map(|v| v.set_float2(model.block_light, model.sky_light)); - collection.shader.model_matrix.map(|v| v.set_matrix4_multi(&model.matrix)); - collection.shader.color_mul.map(|v| v.set_float_mutli_raw(model.colors.as_ptr() as *const _, model.colors.len())); + collection + .shader + .lighting + .map(|v| v.set_float2(model.block_light, model.sky_light)); + collection + .shader + .model_matrix + .map(|v| v.set_matrix4_multi(&model.matrix)); + collection.shader.color_mul.map(|v| { + v.set_float_mutli_raw(model.colors.as_ptr() as *const _, model.colors.len()) + }); gl::draw_elements(gl::TRIANGLES, model.count, self.index_type, 0); } } @@ -301,23 +363,44 @@ init_shader! { // Helper methods pub fn append_box( verts: &mut Vec, - x: f32, y: f32, z: f32, - w: f32, h: f32, d: f32, textures: [Option; 6] + x: f32, + y: f32, + z: f32, + w: f32, + h: f32, + d: f32, + textures: [Option; 6], ) { - append_box_texture_scale(verts, x, y, z, w, h, d, textures, [ - [1.0, 1.0], - [1.0, 1.0], - [1.0, 1.0], - [1.0, 1.0], - [1.0, 1.0], - [1.0, 1.0] - ]); + append_box_texture_scale( + verts, + x, + y, + z, + w, + h, + d, + textures, + [ + [1.0, 1.0], + [1.0, 1.0], + [1.0, 1.0], + [1.0, 1.0], + [1.0, 1.0], + [1.0, 1.0], + ], + ); } pub fn append_box_texture_scale( verts: &mut Vec, - x: f32, y: f32, z: f32, - w: f32, h: f32, d: f32, - textures: [Option; 6], texture_scale: [[f64; 2]; 6]) { + x: f32, + y: f32, + z: f32, + w: f32, + h: f32, + d: f32, + textures: [Option; 6], + texture_scale: [[f64; 2]; 6], +) { for dir in Direction::all() { let tex = textures[dir.index()].clone(); if tex.is_none() { @@ -326,7 +409,11 @@ pub fn append_box_texture_scale( let tex = tex.unwrap(); for vert in BlockVertex::face_by_direction(dir) { let (rr, gg, bb) = if dir == Direction::West || dir == Direction::East { - ((255.0 * 0.8) as u8, (255.0 * 0.8) as u8, (255.0 * 0.8) as u8) + ( + (255.0 * 0.8) as u8, + (255.0 * 0.8) as u8, + (255.0 * 0.8) as u8, + ) } else { (255, 255, 255) }; @@ -356,7 +443,7 @@ pub struct FormatState<'a> { pub x_scale: f32, } -impl <'a> FormatState<'a> { +impl<'a> FormatState<'a> { pub fn build(&mut self, c: &Component, color: format::Color) { match *c { format::Component::Text(ref txt) => { diff --git a/src/render/shaders.rs b/src/render/shaders.rs index a50803c..bdd2f7c 100644 --- a/src/render/shaders.rs +++ b/src/render/shaders.rs @@ -12,12 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::render::glsl; use crate::gl; +use crate::render::glsl; use log::error; pub fn add_shaders(reg: &mut glsl::Registry) { - reg.register("lookup_texture", include_str!("shaders/lookup_texture.glsl")); + reg.register( + "lookup_texture", + include_str!("shaders/lookup_texture.glsl"), + ); reg.register("get_light", include_str!("shaders/get_light.glsl")); reg.register("ui_vertex", include_str!("shaders/ui_vertex.glsl")); @@ -41,12 +44,12 @@ pub fn add_shaders(reg: &mut glsl::Registry) { } macro_rules! get_shader { - ($reg:ident, $name:expr) => ( + ($reg:ident, $name:expr) => { $reg.get($name) - ); - ($reg:ident, $name:expr, $def:expr) => ( + }; + ($reg:ident, $name:expr, $def:expr) => { $reg.get_define($name, $def) - ) + }; } #[macro_export] diff --git a/src/render/ui.rs b/src/render/ui.rs index ea1a92d..bea74d4 100644 --- a/src/render/ui.rs +++ b/src/render/ui.rs @@ -12,16 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::sync::{Arc, RwLock}; -use std::collections::HashMap; -use crate::resources; use crate::gl; use crate::render; use crate::render::glsl; use crate::render::shaders; -use byteorder::{WriteBytesExt, NativeEndian}; +use crate::resources; +use byteorder::{NativeEndian, WriteBytesExt}; use image; use image::GenericImageView; +use std::collections::HashMap; +use std::sync::{Arc, RwLock}; const UI_WIDTH: f64 = 854.0; const UI_HEIGHT: f64 = 480.0; @@ -69,10 +69,11 @@ init_shader! { } impl UIState { - pub fn new(glsl: &glsl::Registry, - textures: Arc>, - res: Arc>) - -> UIState { + pub fn new( + glsl: &glsl::Registry, + textures: Arc>, + res: Arc>, + ) -> UIState { let shader = UIShader::new(glsl); let array = gl::VertexArray::new(); @@ -84,9 +85,15 @@ impl UIState { shader.texture_offset.enable(); shader.color.enable(); shader.position.vertex_pointer_int(3, gl::SHORT, 28, 0); - shader.texture_info.vertex_pointer(4, gl::UNSIGNED_SHORT, false, 28, 8); - shader.texture_offset.vertex_pointer_int(3, gl::SHORT, 28, 16); - shader.color.vertex_pointer(4, gl::UNSIGNED_BYTE, true, 28, 24); + shader + .texture_info + .vertex_pointer(4, gl::UNSIGNED_SHORT, false, 28, 8); + shader + .texture_offset + .vertex_pointer_int(3, gl::SHORT, 28, 16); + shader + .color + .vertex_pointer(4, gl::UNSIGNED_BYTE, true, 28, 24); let index_buffer = gl::Buffer::new(); index_buffer.bind(gl::ELEMENT_ARRAY_BUFFER); @@ -155,17 +162,21 @@ impl UIState { let (data, ty) = render::generate_element_buffer(self.count); self.index_type = ty; self.index_buffer.bind(gl::ELEMENT_ARRAY_BUFFER); - self.index_buffer.set_data(gl::ELEMENT_ARRAY_BUFFER, &data, gl::DYNAMIC_DRAW); + self.index_buffer + .set_data(gl::ELEMENT_ARRAY_BUFFER, &data, gl::DYNAMIC_DRAW); self.max_index = self.count; } - self.shader.screensize.set_float2(width as f32, height as f32); + self.shader + .screensize + .set_float2(width as f32, height as f32); self.buffer.bind(gl::ARRAY_BUFFER); self.index_buffer.bind(gl::ELEMENT_ARRAY_BUFFER); if self.data.len() > self.prev_size { self.prev_size = self.data.len(); - self.buffer.set_data(gl::ARRAY_BUFFER, &self.data, gl::STREAM_DRAW); + self.buffer + .set_data(gl::ARRAY_BUFFER, &self.data, gl::STREAM_DRAW); } else { self.buffer.re_set_data(gl::ARRAY_BUFFER, &self.data); } @@ -209,15 +220,19 @@ impl UIState { if page == 0 { let sw = (self.page_width / 16.0) as u32; let sh = (self.page_height / 16.0) as u32; - return p.relative((cx * sw + info.0 as u32) as f32 / (self.page_width as f32), - (cy * sh) as f32 / (self.page_height as f32), - (info.1 - info.0) as f32 / (self.page_width as f32), - (sh as f32) / (self.page_height as f32)) + return p.relative( + (cx * sw + info.0 as u32) as f32 / (self.page_width as f32), + (cy * sh) as f32 / (self.page_height as f32), + (info.1 - info.0) as f32 / (self.page_width as f32), + (sh as f32) / (self.page_height as f32), + ); } - p.relative((cx * 16 + info.0 as u32) as f32 / 256.0, - (cy * 16) as f32 / 256.0, - (info.1 - info.0) as f32 / 256.0, - 16.0 / 256.0) + p.relative( + (cx * 16 + info.0 as u32) as f32 / 256.0, + (cy * 16) as f32 / 256.0, + (info.1 - info.0) as f32 / 256.0, + 16.0 / 256.0, + ) } pub fn size_of_string(&self, val: &str) -> f64 { @@ -296,44 +311,47 @@ impl UIState { self.new_text_scaled(val, x, y, 1.0, 1.0, r, g, b) } - pub fn new_text_scaled(&mut self, - val: &str, - x: f64, - y: f64, - sx: f64, - sy: f64, - r: u8, - g: u8, - b: u8) - -> UIText { + pub fn new_text_scaled( + &mut self, + val: &str, + x: f64, + y: f64, + sx: f64, + sy: f64, + r: u8, + g: u8, + b: u8, + ) -> UIText { self.create_text(val, x, y, sx, sy, 0.0, r, g, b) } - pub fn new_text_rotated(&mut self, - val: &str, - x: f64, - y: f64, - sx: f64, - sy: f64, - rotation: f64, - r: u8, - g: u8, - b: u8) - -> UIText { + pub fn new_text_rotated( + &mut self, + val: &str, + x: f64, + y: f64, + sx: f64, + sy: f64, + rotation: f64, + r: u8, + g: u8, + b: u8, + ) -> UIText { self.create_text(val, x, y, sx, sy, rotation, r, g, b) } - fn create_text(&mut self, - val: &str, - x: f64, - y: f64, - sx: f64, - sy: f64, - rotation: f64, - r: u8, - g: u8, - b: u8) - -> UIText { + fn create_text( + &mut self, + val: &str, + x: f64, + y: f64, + sx: f64, + sy: f64, + rotation: f64, + r: u8, + g: u8, + b: u8, + ) -> UIText { let mut elements = Vec::new(); let mut offset = 0.0; for ch in val.chars() { @@ -361,30 +379,34 @@ impl UIState { dy = (16.0 * 0.5) + (tmpy * c + tmpx * s); } - let mut shadow = UIElement::new(&texture, - x + dsx * sx, - y + dsy * sy, - w * sx, - 16.0 * sy, - 0.0, - 0.0, - 1.0, - 1.0); + let mut shadow = UIElement::new( + &texture, + x + dsx * sx, + y + dsy * sy, + w * sx, + 16.0 * sy, + 0.0, + 0.0, + 1.0, + 1.0, + ); shadow.r = ((r as f64) * 0.25) as u8; shadow.g = ((g as f64) * 0.25) as u8; shadow.b = ((b as f64) * 0.25) as u8; shadow.rotation = rotation; elements.push(shadow); - let mut text = UIElement::new(&texture, - x + dx * sx, - y + dy * sy, - w * sx, - 16.0 * sy, - 0.0, - 0.0, - 1.0, - 1.0); + let mut text = UIElement::new( + &texture, + x + dx * sx, + y + dy * sy, + w * sx, + 16.0 * sy, + 0.0, + 0.0, + 1.0, + 1.0, + ); text.r = r; text.g = g; text.b = b; @@ -437,16 +459,17 @@ pub struct UIElement { } impl UIElement { - pub fn new(tex: &render::Texture, - x: f64, - y: f64, - width: f64, - height: f64, - tx: f64, - ty: f64, - tw: f64, - th: f64) - -> UIElement { + pub fn new( + tex: &render::Texture, + x: f64, + y: f64, + width: f64, + height: f64, + tx: f64, + ty: f64, + tw: f64, + th: f64, + ) -> UIElement { let twidth = tex.get_width(); let theight = tex.get_height(); UIElement { @@ -474,46 +497,56 @@ impl UIElement { pub fn bytes(&self, width: f64, height: f64) -> Vec { let mut buf = Vec::with_capacity(28 * 4); - self.append_vertex(&mut buf, - self.x, - self.y, - self.t_offsetx, - self.t_offsety, - width, - height); - self.append_vertex(&mut buf, - self.x + self.w, - self.y, - self.t_offsetx + self.t_sizew, - self.t_offsety, - width, - height); - self.append_vertex(&mut buf, - self.x, - self.y + self.h, - self.t_offsetx, - self.t_offsety + self.t_sizeh, - width, - height); - self.append_vertex(&mut buf, - self.x + self.w, - self.y + self.h, - self.t_offsetx + self.t_sizew, - self.t_offsety + self.t_sizeh, - width, - height); + self.append_vertex( + &mut buf, + self.x, + self.y, + self.t_offsetx, + self.t_offsety, + width, + height, + ); + self.append_vertex( + &mut buf, + self.x + self.w, + self.y, + self.t_offsetx + self.t_sizew, + self.t_offsety, + width, + height, + ); + self.append_vertex( + &mut buf, + self.x, + self.y + self.h, + self.t_offsetx, + self.t_offsety + self.t_sizeh, + width, + height, + ); + self.append_vertex( + &mut buf, + self.x + self.w, + self.y + self.h, + self.t_offsetx + self.t_sizew, + self.t_offsety + self.t_sizeh, + width, + height, + ); buf } #[allow(unused_must_use)] - pub fn append_vertex(&self, - buf: &mut Vec, - x: f64, - y: f64, - tx: i16, - ty: i16, - width: f64, - height: f64) { + pub fn append_vertex( + &self, + buf: &mut Vec, + x: f64, + y: f64, + tx: i16, + ty: i16, + width: f64, + height: f64, + ) { let mut dx = x as f64; let mut dy = y as f64; if self.rotation != 0.0 { diff --git a/src/resources.rs b/src/resources.rs index 9ebad80..50589fa 100644 --- a/src/resources.rs +++ b/src/resources.rs @@ -14,15 +14,15 @@ extern crate steven_resources as internal; -use std::thread; -use std::path; -use std::io; -use std_or_web::fs; -use std::sync::mpsc; -use std::sync::{Arc, Mutex}; +use serde_json; use std::collections::HashMap; use std::hash::BuildHasherDefault; -use serde_json; +use std::io; +use std::path; +use std::sync::mpsc; +use std::sync::{Arc, Mutex}; +use std::thread; +use std_or_web::fs; #[cfg(not(target_arch = "wasm32"))] use reqwest; @@ -32,7 +32,8 @@ use crate::types::hash::FNVHash; use crate::ui; const RESOURCES_VERSION: &str = "1.12.2"; -const VANILLA_CLIENT_URL: &str = "https://launcher.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar"; +const VANILLA_CLIENT_URL: &str = + "https://launcher.mojang.com/v1/objects/0f275bc1547d01fa5f56ba34bdc87d981ee12daf/client.jar"; const ASSET_VERSION: &str = "1.12"; const ASSET_INDEX_URL: &str = "https://launchermeta.mojang.com/mc/assets/1.12/67e29e024e664064c1f04c728604f83c24cbc218/1.12.json"; @@ -85,9 +86,7 @@ impl Manager { version: 0, vanilla_chan: None, vanilla_assets_chan: None, - vanilla_progress: Arc::new(Mutex::new(Progress { - tasks: vec![], - })), + vanilla_progress: Arc::new(Mutex::new(Progress { tasks: vec![] })), }; m.add_pack(Box::new(InternalPack)); #[cfg(not(target_arch = "wasm32"))] @@ -95,7 +94,13 @@ impl Manager { m.download_vanilla(); m.download_assets(); } - (m, ManagerUI { progress_ui: vec!{}, num_tasks: 0 }) + ( + m, + ManagerUI { + progress_ui: vec![], + num_tasks: 0, + }, + ) } /// Returns the 'version' of the manager. The version is @@ -156,9 +161,12 @@ impl Manager { progress.tasks.retain(|v| v.progress < v.total); // Find out what we have to work with for task in &progress.tasks { - if !mui.progress_ui.iter() + if !mui + .progress_ui + .iter() .filter(|v| v.task_file == task.task_file) - .any(|v| v.task_name == task.task_name) { + .any(|v| v.task_name == task.task_name) + { mui.num_tasks += 1; // Add a ui element for it let background = ui::ImageBuilder::new() @@ -217,16 +225,22 @@ impl Manager { } let mut found = false; let mut prog = 1.0; - for task in progress.tasks.iter() + for task in progress + .tasks + .iter() .filter(|v| v.task_file == ui.task_file) - .filter(|v| v.task_name == ui.task_name) { + .filter(|v| v.task_name == ui.task_name) + { found = true; prog = task.progress as f64 / task.total as f64; } let background = ui.background.borrow(); let bar = ui.progress_bar.borrow(); // Let the progress bar finish - if !found && (background.y - ui.position).abs() < 0.7 * delta && (bar.width - 350.0).abs() < 1.0 * delta { + if !found + && (background.y - ui.position).abs() < 0.7 * delta + && (bar.width - 350.0).abs() < 1.0 * delta + { ui.closing = true; ui.position = -UI_HEIGHT; } @@ -258,7 +272,8 @@ impl Manager { } // Clean up dead elements - mui.progress_ui.retain(|v| v.position >= -UI_HEIGHT || !v.closing); + mui.progress_ui + .retain(|v| v.position >= -UI_HEIGHT || !v.closing); } fn add_pack(&mut self, pck: Box) { @@ -269,7 +284,12 @@ impl Manager { fn load_vanilla(&mut self) { let loc = format!("./resources-{}", RESOURCES_VERSION); let location = path::Path::new(&loc); - self.packs.insert(1, Box::new(DirPack { root: location.to_path_buf() })); + self.packs.insert( + 1, + Box::new(DirPack { + root: location.to_path_buf(), + }), + ); self.version += 1; } @@ -284,23 +304,34 @@ impl Manager { let location = path::Path::new(&loc).to_owned(); let progress_info = self.vanilla_progress.clone(); let (send, recv) = mpsc::channel(); - if fs::metadata(&location).is_ok(){ + if fs::metadata(&location).is_ok() { self.load_assets(); } else { self.vanilla_assets_chan = Some(recv); } thread::spawn(move || { let client = reqwest::blocking::Client::new(); - if fs::metadata(&location).is_err(){ + if fs::metadata(&location).is_err() { fs::create_dir_all(location.parent().unwrap()).unwrap(); - let res = client.get(ASSET_INDEX_URL) - .send() - .unwrap(); + let res = client.get(ASSET_INDEX_URL).send().unwrap(); - let length = res.headers().get(reqwest::header::CONTENT_LENGTH).unwrap().to_str().unwrap().parse::().unwrap(); - Self::add_task(&progress_info, "Downloading Asset Index", &*location.to_string_lossy(), length); + let length = res + .headers() + .get(reqwest::header::CONTENT_LENGTH) + .unwrap() + .to_str() + .unwrap() + .parse::() + .unwrap(); + Self::add_task( + &progress_info, + "Downloading Asset Index", + &*location.to_string_lossy(), + length, + ); { - let mut file = fs::File::create(format!("index-{}.tmp", ASSET_VERSION)).unwrap(); + let mut file = + fs::File::create(format!("index-{}.tmp", ASSET_VERSION)).unwrap(); let mut progress = ProgressRead { read: res, progress: &progress_info, @@ -316,16 +347,25 @@ impl Manager { let index: serde_json::Value = serde_json::from_reader(&file).unwrap(); let root_location = path::Path::new("./objects/"); let objects = index.get("objects").and_then(|v| v.as_object()).unwrap(); - Self::add_task(&progress_info, "Downloading Assets", "./objects", objects.len() as u64); + Self::add_task( + &progress_info, + "Downloading Assets", + "./objects", + objects.len() as u64, + ); for (k, v) in objects { let hash = v.get("hash").and_then(|v| v.as_str()).unwrap(); let hash_path = format!("{}/{}", &hash[..2], hash); let location = root_location.join(&hash_path); - if fs::metadata(&location).is_err(){ + if fs::metadata(&location).is_err() { fs::create_dir_all(location.parent().unwrap()).unwrap(); - let res = client.get(&format!("http://resources.download.minecraft.net/{}", hash_path)) - .send() - .unwrap(); + let res = client + .get(&format!( + "http://resources.download.minecraft.net/{}", + hash_path + )) + .send() + .unwrap(); let length = v.get("size").and_then(|v| v.as_u64()).unwrap(); Self::add_task(&progress_info, "Downloading Asset", k, length); let mut tmp_file = location.to_owned(); @@ -361,14 +401,24 @@ impl Manager { let progress_info = self.vanilla_progress.clone(); thread::spawn(move || { let client = reqwest::blocking::Client::new(); - let res = client.get(VANILLA_CLIENT_URL) - .send() - .unwrap(); + let res = client.get(VANILLA_CLIENT_URL).send().unwrap(); let mut file = fs::File::create(format!("{}.tmp", RESOURCES_VERSION)).unwrap(); - let length = res.headers().get(reqwest::header::CONTENT_LENGTH).unwrap().to_str().unwrap().parse::().unwrap(); + let length = res + .headers() + .get(reqwest::header::CONTENT_LENGTH) + .unwrap() + .to_str() + .unwrap() + .parse::() + .unwrap(); let task_file = format!("./resources-{}", RESOURCES_VERSION); - Self::add_task(&progress_info, "Downloading Core Assets", &task_file, length); + Self::add_task( + &progress_info, + "Downloading Core Assets", + &task_file, + length, + ); { let mut progress = ProgressRead { read: res, @@ -384,7 +434,12 @@ impl Manager { let mut zip = zip::ZipArchive::new(file).unwrap(); let task_file = format!("./resources-{}", RESOURCES_VERSION); - Self::add_task(&progress_info, "Unpacking Core Assets", &task_file, zip.len() as u64); + Self::add_task( + &progress_info, + "Unpacking Core Assets", + &task_file, + zip.len() as u64, + ); let loc = format!("./resources-{}", RESOURCES_VERSION); let location = path::Path::new(&loc); @@ -420,9 +475,12 @@ impl Manager { fn add_task_progress(progress: &Arc>, name: &str, file: &str, prog: u64) { let mut progress = progress.lock().unwrap(); - for task in progress.tasks.iter_mut() + for task in progress + .tasks + .iter_mut() .filter(|v| v.task_file == file) - .filter(|v| v.task_name == name) { + .filter(|v| v.task_name == name) + { task.progress += prog as u64; } } @@ -465,11 +523,12 @@ impl ObjectPack { let objects = index.get("objects").and_then(|v| v.as_object()).unwrap(); let mut hash_objs = HashMap::with_hasher(BuildHasherDefault::default()); for (k, v) in objects { - hash_objs.insert(k.clone(), v.get("hash").and_then(|v| v.as_str()).unwrap().to_owned()); - } - ObjectPack { - objects: hash_objs, + hash_objs.insert( + k.clone(), + v.get("hash").and_then(|v| v.as_str()).unwrap().to_owned(), + ); } + ObjectPack { objects: hash_objs } } } @@ -500,7 +559,7 @@ struct ProgressRead<'a, T> { task_file: String, } -impl <'a, T: io::Read> io::Read for ProgressRead<'a, T> { +impl<'a, T: io::Read> io::Read for ProgressRead<'a, T> { fn read(&mut self, buf: &mut [u8]) -> io::Result { let size = self.read.read(buf)?; Manager::add_task_progress(self.progress, &self.task_name, &self.task_file, size as u64); diff --git a/src/screen/connecting.rs b/src/screen/connecting.rs index fc10386..9f37ef0 100644 --- a/src/screen/connecting.rs +++ b/src/screen/connecting.rs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::ui; use crate::render; +use crate::ui; pub struct Connecting { elements: Option, @@ -27,7 +27,6 @@ struct UIElements { _disclaimer: ui::TextRef, } - impl Connecting { pub fn new(target: &str) -> Connecting { Connecting { @@ -74,10 +73,12 @@ impl super::Screen for Connecting { self.elements = None } - fn tick(&mut self, - _delta: f64, - renderer: &mut render::Renderer, - _ui_container: &mut ui::Container) -> Option>{ + fn tick( + &mut self, + _delta: f64, + renderer: &mut render::Renderer, + _ui_container: &mut ui::Container, + ) -> Option> { let elements = self.elements.as_mut().unwrap(); elements.logo.tick(renderer); diff --git a/src/screen/edit_server.rs b/src/screen/edit_server.rs index dacd3ec..e721737 100644 --- a/src/screen/edit_server.rs +++ b/src/screen/edit_server.rs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std_or_web::fs; use std::collections::BTreeMap; +use std_or_web::fs; -use crate::ui; use crate::render; +use crate::ui; use serde_json::{self, Value}; @@ -60,7 +60,8 @@ impl EditServerEntry { }; { - let servers = servers_info.as_object_mut() + let servers = servers_info + .as_object_mut() .unwrap() .get_mut("servers") .unwrap() @@ -76,7 +77,6 @@ impl EditServerEntry { let mut out = fs::File::create("servers.json").unwrap(); serde_json::to_writer_pretty(&mut out, &servers_info).unwrap(); } - } impl super::Screen for EditServerEntry { @@ -131,7 +131,8 @@ impl super::Screen for EditServerEntry { &server_name.borrow().input, &server_address.borrow().input, ); - game.screen_sys.replace_screen(Box::new(super::ServerList::new(None))); + game.screen_sys + .replace_screen(Box::new(super::ServerList::new(None))); true }); } @@ -150,7 +151,8 @@ impl super::Screen for EditServerEntry { .attach(&mut *cancel); cancel.add_text(txt); cancel.add_click_func(|_, game| { - game.screen_sys.replace_screen(Box::new(super::ServerList::new(None))); + game.screen_sys + .replace_screen(Box::new(super::ServerList::new(None))); true }); } @@ -169,11 +171,12 @@ impl super::Screen for EditServerEntry { self.elements = None } - fn tick(&mut self, - _delta: f64, - renderer: &mut render::Renderer, - _ui_container: &mut ui::Container) -> Option> { - + fn tick( + &mut self, + _delta: f64, + renderer: &mut render::Renderer, + _ui_container: &mut ui::Container, + ) -> Option> { let elements = self.elements.as_mut().unwrap(); elements.logo.tick(renderer); None diff --git a/src/screen/login.rs b/src/screen/login.rs index b5cacc4..784554b 100644 --- a/src/screen/login.rs +++ b/src/screen/login.rs @@ -19,12 +19,12 @@ use std::thread; use rand::{self, Rng}; -use crate::ui; -use crate::render; +use crate::auth; use crate::console; use crate::protocol; use crate::protocol::mojang; -use crate::auth; +use crate::render; +use crate::ui; pub struct Login { elements: Option, @@ -47,10 +47,12 @@ struct UIElements { profile: mojang::Profile, } - impl Login { pub fn new(vars: Rc) -> Login { - Login { elements: None, vars: vars } + Login { + elements: None, + vars: vars, + } } } @@ -82,7 +84,6 @@ impl super::Screen for Login { }); } - // Login Error let login_error = ui::TextBuilder::new() .text("") @@ -157,10 +158,12 @@ impl super::Screen for Login { self.elements = None } - fn tick(&mut self, - _delta: f64, - renderer: &mut render::Renderer, - _ui_container: &mut ui::Container) -> Option> { + fn tick( + &mut self, + _delta: f64, + renderer: &mut render::Renderer, + _ui_container: &mut ui::Container, + ) -> Option> { let elements = self.elements.as_mut().unwrap(); if elements.try_login.get() && elements.login_res.is_none() { @@ -171,10 +174,10 @@ impl super::Screen for Login { elements.login_btn_text.borrow_mut().text = "Logging in...".into(); let mut client_token = self.vars.get(auth::AUTH_CLIENT_TOKEN).clone(); if client_token.is_empty() { - client_token = std::iter::repeat(()).map(|()| rand::thread_rng() - .sample(&rand::distributions::Alphanumeric)) - .take(20) - .collect(); + client_token = std::iter::repeat(()) + .map(|()| rand::thread_rng().sample(&rand::distributions::Alphanumeric)) + .take(20) + .collect(); self.vars.set(auth::AUTH_CLIENT_TOKEN, client_token); } let client_token = self.vars.get(auth::AUTH_CLIENT_TOKEN).clone(); @@ -186,7 +189,8 @@ impl super::Screen for Login { if refresh { tx.send(profile.refresh(&client_token)).unwrap(); } else { - tx.send(mojang::Profile::login(&username, &password, &client_token)).unwrap(); + tx.send(mojang::Profile::login(&username, &password, &client_token)) + .unwrap(); } }); } @@ -203,10 +207,10 @@ impl super::Screen for Login { self.vars.set(auth::AUTH_TOKEN, val.access_token.clone()); elements.profile = val; return Some(Box::new(super::ServerList::new(None))); - }, + } Err(err) => { elements.login_error.borrow_mut().text = format!("{}", err); - }, + } } } } diff --git a/src/screen/mod.rs b/src/screen/mod.rs index b10dab1..057e2a7 100644 --- a/src/screen/mod.rs +++ b/src/screen/mod.rs @@ -21,31 +21,30 @@ pub mod connecting; pub mod edit_server; pub mod settings_menu; -pub use self::settings_menu::{SettingsMenu, VideoSettingsMenu, AudioSettingsMenu}; +pub use self::settings_menu::{AudioSettingsMenu, SettingsMenu, VideoSettingsMenu}; use crate::render; use crate::ui; pub trait Screen { // Called once - fn init(&mut self, _renderer: &mut render::Renderer, _ui_container: &mut ui::Container) { - } - fn deinit(&mut self, _renderer: &mut render::Renderer, _ui_container: &mut ui::Container) { - } + fn init(&mut self, _renderer: &mut render::Renderer, _ui_container: &mut ui::Container) {} + fn deinit(&mut self, _renderer: &mut render::Renderer, _ui_container: &mut ui::Container) {} // May be called multiple times fn on_active(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container); fn on_deactive(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container); // Called every frame the screen is active - fn tick(&mut self, - delta: f64, - renderer: &mut render::Renderer, - ui_container: &mut ui::Container) -> Option>; + fn tick( + &mut self, + delta: f64, + renderer: &mut render::Renderer, + ui_container: &mut ui::Container, + ) -> Option>; // Events - fn on_scroll(&mut self, _x: f64, _y: f64) { - } + fn on_scroll(&mut self, _x: f64, _y: f64) {} fn is_closable(&self) -> bool { false @@ -65,7 +64,9 @@ pub struct ScreenSystem { } impl ScreenSystem { - pub fn new() -> ScreenSystem { Default::default() } + pub fn new() -> ScreenSystem { + Default::default() + } pub fn add_screen(&mut self, screen: Box) { self.screens.push(ScreenInfo { @@ -94,10 +95,12 @@ impl ScreenSystem { } } - pub fn tick(&mut self, - delta: f64, - renderer: &mut render::Renderer, - ui_container: &mut ui::Container) { + pub fn tick( + &mut self, + delta: f64, + renderer: &mut render::Renderer, + ui_container: &mut ui::Container, + ) { for screen in &mut self.remove_queue { if screen.active { screen.screen.on_deactive(renderer, ui_container); diff --git a/src/screen/server_list.rs b/src/screen/server_list.rs index 10e4829..dbbbc9a 100644 --- a/src/screen/server_list.rs +++ b/src/screen/server_list.rs @@ -12,24 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std_or_web::fs; -use std::thread; -use std::sync::mpsc; -use std::rc::Rc; use std::cell::RefCell; +use std::rc::Rc; +use std::sync::mpsc; +use std::thread; +use std_or_web::fs; -use crate::ui; -use crate::render; use crate::format; use crate::format::{Component, TextComponent}; use crate::protocol; +use crate::render; +use crate::ui; -use serde_json; -use std::time::{Duration}; -use image; use base64; +use image; use rand; use rand::Rng; +use serde_json; +use std::time::Duration; pub struct ServerList { elements: Option, @@ -98,9 +98,11 @@ impl ServerList { } } - fn reload_server_list(&mut self, - renderer: &mut render::Renderer, - ui_container: &mut ui::Container) { + fn reload_server_list( + &mut self, + renderer: &mut render::Renderer, + ui_container: &mut ui::Container, + ) { let elements = self.elements.as_mut().unwrap(); *self.needs_reload.borrow_mut() = false; { @@ -141,15 +143,12 @@ impl ServerList { let mut backr = back.borrow_mut(); let address = address.clone(); backr.add_hover_func(move |this, over, _| { - this.colour.3 = if over { - 200 - } else { - 100 - }; + this.colour.3 = if over { 200 } else { 100 }; false }); backr.add_click_func(move |_, game| { - game.screen_sys.replace_screen(Box::new(super::connecting::Connecting::new(&address))); + game.screen_sys + .replace_screen(Box::new(super::connecting::Connecting::new(&address))); game.connect_to(&address); true }); @@ -168,7 +167,6 @@ impl ServerList { .size(90.0, 90.0) .attach(&mut *back.borrow_mut()); - // Ping indicator let ping = ui::ImageBuilder::new() .texture("gui/icons") @@ -232,9 +230,13 @@ impl ServerList { let sname = name.clone(); let saddr = address.clone(); btn.add_click_func(move |_, game| { - game.screen_sys.replace_screen(Box::new(super::edit_server::EditServerEntry::new( - Some((index, sname.clone(), saddr.clone())) - ))); + game.screen_sys.replace_screen(Box::new( + super::edit_server::EditServerEntry::new(Some(( + index, + sname.clone(), + saddr.clone(), + ))), + )); true }) } @@ -260,7 +262,9 @@ impl ServerList { // Don't block the main thread whilst pinging the server thread::spawn(move || { - match protocol::Conn::new(&address, protocol::SUPPORTED_PROTOCOLS[0]).and_then(|conn| conn.do_status()) { + match protocol::Conn::new(&address, protocol::SUPPORTED_PROTOCOLS[0]) + .and_then(|conn| conn.do_status()) + { Ok(res) => { let mut desc = res.0.description; format::convert_legacy(&mut desc); @@ -345,9 +349,8 @@ impl super::Screen for ServerList { .attach(&mut *add); add.add_text(txt); add.add_click_func(move |_, game| { - game.screen_sys.replace_screen(Box::new(super::edit_server::EditServerEntry::new( - None - ))); + game.screen_sys + .replace_screen(Box::new(super::edit_server::EditServerEntry::new(None))); true }) } @@ -367,7 +370,8 @@ impl super::Screen for ServerList { .alignment(ui::VAttach::Middle, ui::HAttach::Center) .attach(&mut *options); options.add_click_func(|_, game| { - game.screen_sys.add_screen(Box::new(super::SettingsMenu::new(game.vars.clone(), false))); + game.screen_sys + .add_screen(Box::new(super::SettingsMenu::new(game.vars.clone(), false))); true }); } @@ -386,7 +390,10 @@ impl super::Screen for ServerList { let background = ui::ImageBuilder::new() .texture("steven:solid") .position(0.0, 3.0) - .size(width.max(renderer.ui.size_of_string("Disconnected")) + 4.0, height + 4.0 + 16.0) + .size( + width.max(renderer.ui.size_of_string("Disconnected")) + 4.0, + height + 4.0 + 16.0, + ) .colour((0, 0, 0, 100)) .alignment(ui::VAttach::Top, ui::HAttach::Center) .draw_index(10) @@ -435,10 +442,12 @@ impl super::Screen for ServerList { self.elements = None } - fn tick(&mut self, - delta: f64, - renderer: &mut render::Renderer, - ui_container: &mut ui::Container) -> Option> { + fn tick( + &mut self, + delta: f64, + renderer: &mut render::Renderer, + ui_container: &mut ui::Container, + ) -> Option> { if *self.needs_reload.borrow() { self.reload_server_list(renderer, ui_container); } @@ -468,20 +477,23 @@ impl super::Screen for ServerList { s.motd.borrow_mut().set_text(res.motd); // Selects the icon for the given ping range // TODO: switch to as_millis() experimental duration_as_u128 #50202 once available? - let ping_ms = (res.ping.subsec_nanos() as f64)/1000000.0 + (res.ping.as_secs() as f64)*1000.0; + let ping_ms = (res.ping.subsec_nanos() as f64) / 1000000.0 + + (res.ping.as_secs() as f64) * 1000.0; let y = match ping_ms.round() as u64 { - _x @ 0 ..= 75 => 16.0 / 256.0, - _x @ 76 ..= 150 => 24.0 / 256.0, - _x @ 151 ..= 225 => 32.0 / 256.0, - _x @ 226 ..= 350 => 40.0 / 256.0, - _x @ 351 ..= 999 => 48.0 / 256.0, + _x @ 0..=75 => 16.0 / 256.0, + _x @ 76..=150 => 24.0 / 256.0, + _x @ 151..=225 => 32.0 / 256.0, + _x @ 226..=350 => 40.0 / 256.0, + _x @ 351..=999 => 48.0 / 256.0, _ => 56.0 / 256.0, }; s.ping.borrow_mut().texture_coords.1 = y; if res.exists { { let mut players = s.players.borrow_mut(); - let txt = if protocol::SUPPORTED_PROTOCOLS.contains(&res.protocol_version) { + let txt = if protocol::SUPPORTED_PROTOCOLS + .contains(&res.protocol_version) + { players.colour.1 = 255; players.colour.2 = 255; format!("{}/{}", res.online, res.max) @@ -492,8 +504,13 @@ impl super::Screen for ServerList { }; players.text = txt; } - let sm = format!("{} mods + {}", res.forge_mods.len(), res.protocol_name); - let st = if res.forge_mods.len() > 0 { &sm } else { &res.protocol_name }; + let sm = + format!("{} mods + {}", res.forge_mods.len(), res.protocol_name); + let st = if res.forge_mods.len() > 0 { + &sm + } else { + &res.protocol_name + }; let mut txt = TextComponent::new(&st); txt.modifier.color = Some(format::Color::Yellow); let mut msg = Component::Text(txt); @@ -501,15 +518,15 @@ impl super::Screen for ServerList { s.version.borrow_mut().set_text(msg); } if let Some(favicon) = res.favicon { - let name: String = std::iter::repeat(()).map(|()| rand::thread_rng() - .sample(&rand::distributions::Alphanumeric)) - .take(30) - .collect(); + let name: String = std::iter::repeat(()) + .map(|()| { + rand::thread_rng().sample(&rand::distributions::Alphanumeric) + }) + .take(30) + .collect(); let tex = renderer.get_textures_ref(); s.icon_texture = Some(name.clone()); - let icon_tex = tex.write() - .unwrap() - .put_dynamic(&name, favicon); + let icon_tex = tex.write().unwrap().put_dynamic(&name, favicon); s.icon.borrow_mut().texture = icon_tex.name; } } diff --git a/src/screen/settings_menu.rs b/src/screen/settings_menu.rs index 34de1fd..f44cc40 100644 --- a/src/screen/settings_menu.rs +++ b/src/screen/settings_menu.rs @@ -1,7 +1,7 @@ use crate::console; use crate::render; -use crate::ui; use crate::settings; +use crate::ui; use std::rc::Rc; @@ -13,7 +13,7 @@ pub struct UIElements { pub struct SettingsMenu { _vars: Rc, elements: Option, - show_disconnect_button: bool + show_disconnect_button: bool, } impl SettingsMenu { @@ -21,7 +21,7 @@ impl SettingsMenu { SettingsMenu { _vars: vars, elements: None, - show_disconnect_button: show_disconnect_button + show_disconnect_button: show_disconnect_button, } } } @@ -51,7 +51,8 @@ impl super::Screen for SettingsMenu { .attach(&mut *audio_settings); audio_settings.add_text(txt); audio_settings.add_click_func(|_, game| { - game.screen_sys.add_screen(Box::new(AudioSettingsMenu::new(game.vars.clone()))); + game.screen_sys + .add_screen(Box::new(AudioSettingsMenu::new(game.vars.clone()))); true }); } @@ -70,7 +71,8 @@ impl super::Screen for SettingsMenu { .attach(&mut *video_settings); video_settings.add_text(txt); video_settings.add_click_func(|_, game| { - game.screen_sys.add_screen(Box::new(VideoSettingsMenu::new(game.vars.clone()))); + game.screen_sys + .add_screen(Box::new(VideoSettingsMenu::new(game.vars.clone()))); true }); } @@ -142,7 +144,8 @@ impl super::Screen for SettingsMenu { disconnect_button.add_text(txt); disconnect_button.add_click_func(|_, game| { game.server.disconnect(None); - game.screen_sys.replace_screen(Box::new(super::ServerList::new(None))); + game.screen_sys + .replace_screen(Box::new(super::ServerList::new(None))); true }); } @@ -153,14 +156,18 @@ impl super::Screen for SettingsMenu { background, _buttons: buttons, }); - } fn on_deactive(&mut self, _renderer: &mut render::Renderer, _ui_container: &mut ui::Container) { self.elements = None; } // Called every frame the screen is active - fn tick(&mut self, _delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) -> Option> { + fn tick( + &mut self, + _delta: f64, + renderer: &mut render::Renderer, + ui_container: &mut ui::Container, + ) -> Option> { let elements = self.elements.as_mut().unwrap(); { let mode = ui_container.mode; @@ -178,9 +185,7 @@ impl super::Screen for SettingsMenu { } // Events - fn on_scroll(&mut self, _x: f64, _y: f64) { - - } + fn on_scroll(&mut self, _x: f64, _y: f64) {} fn is_closable(&self) -> bool { true @@ -227,11 +232,14 @@ impl super::Screen for VideoSettingsMenu { { let mut fov_setting = fov_setting.borrow_mut(); let txt = ui::TextBuilder::new() - .text(format!("FOV: {}", match r_fov { - 90 => "Normal".into(), - 110 => "Quake pro".into(), - val => val.to_string(), - })) + .text(format!( + "FOV: {}", + match r_fov { + 90 => "Normal".into(), + 110 => "Quake pro".into(), + val => val.to_string(), + } + )) .alignment(ui::VAttach::Middle, ui::HAttach::Center) .attach(&mut *fov_setting); fov_setting.add_text(txt); @@ -246,14 +254,18 @@ impl super::Screen for VideoSettingsMenu { { let mut vsync_setting = vsync_setting.borrow_mut(); let txt = ui::TextBuilder::new() - .text(format!("VSync: {}", if r_vsync { "Enabled" } else { "Disabled" })) + .text(format!( + "VSync: {}", + if r_vsync { "Enabled" } else { "Disabled" } + )) .alignment(ui::VAttach::Middle, ui::HAttach::Center) .attach(&mut *vsync_setting); let txt_vsync = txt.clone(); vsync_setting.add_text(txt); vsync_setting.add_click_func(move |_, game| { let r_vsync = !*game.vars.get(settings::R_VSYNC); - txt_vsync.borrow_mut().text = format!("VSync: {}", if r_vsync { "Enabled" } else { "Disabled" }); + txt_vsync.borrow_mut().text = + format!("VSync: {}", if r_vsync { "Enabled" } else { "Disabled" }); game.vars.set(settings::R_VSYNC, r_vsync); true }); @@ -269,10 +281,13 @@ impl super::Screen for VideoSettingsMenu { { let mut fps_setting = fps_setting.borrow_mut(); let txt = ui::TextBuilder::new() - .text(format!("FPS cap: {}", match r_max_fps { - 0 => "Unlimited".into(), - val => val.to_string(), - })) + .text(format!( + "FPS cap: {}", + match r_max_fps { + 0 => "Unlimited".into(), + val => val.to_string(), + } + )) .alignment(ui::VAttach::Middle, ui::HAttach::Center) .attach(&mut *fps_setting); fps_setting.add_text(txt); @@ -302,14 +317,18 @@ impl super::Screen for VideoSettingsMenu { background, _buttons: buttons, }); - } fn on_deactive(&mut self, _renderer: &mut render::Renderer, _ui_container: &mut ui::Container) { self.elements = None; } // Called every frame the screen is active - fn tick(&mut self, _delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) -> Option> { + fn tick( + &mut self, + _delta: f64, + renderer: &mut render::Renderer, + ui_container: &mut ui::Container, + ) -> Option> { let elements = self.elements.as_mut().unwrap(); { let mode = ui_container.mode; @@ -327,9 +346,7 @@ impl super::Screen for VideoSettingsMenu { } // Events - fn on_scroll(&mut self, _x: f64, _y: f64) { - - } + fn on_scroll(&mut self, _x: f64, _y: f64) {} fn is_closable(&self) -> bool { true @@ -338,14 +355,14 @@ impl super::Screen for VideoSettingsMenu { pub struct AudioSettingsMenu { _vars: Rc, - elements: Option + elements: Option, } impl AudioSettingsMenu { pub fn new(vars: Rc) -> AudioSettingsMenu { AudioSettingsMenu { _vars: vars, - elements: None + elements: None, } } } @@ -387,14 +404,18 @@ impl super::Screen for AudioSettingsMenu { background, _buttons: buttons, }); - } fn on_deactive(&mut self, _renderer: &mut render::Renderer, _ui_container: &mut ui::Container) { self.elements = None; } // Called every frame the screen is active - fn tick(&mut self, _delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) -> Option> { + fn tick( + &mut self, + _delta: f64, + renderer: &mut render::Renderer, + ui_container: &mut ui::Container, + ) -> Option> { let elements = self.elements.as_mut().unwrap(); { let mode = ui_container.mode; @@ -412,9 +433,7 @@ impl super::Screen for AudioSettingsMenu { } // Events - fn on_scroll(&mut self, _x: f64, _y: f64) { - - } + fn on_scroll(&mut self, _x: f64, _y: f64) {} fn is_closable(&self) -> bool { true diff --git a/src/server/mod.rs b/src/server/mod.rs index f5ec723..a7563db 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -12,32 +12,32 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::protocol::{self, mojang, packet, forge}; -use crate::world; -use crate::world::block; -use rand::{self, Rng}; -use std::sync::{Arc, RwLock}; -use std::sync::mpsc; -use std::thread; -use std::collections::HashMap; -use std::hash::BuildHasherDefault; -use crate::types::hash::FNVHash; -use crate::resources; -use crate::render; -use crate::settings::Stevenkey; use crate::ecs; use crate::entity; -use cgmath::prelude::*; -use crate::types::Gamemode; -use crate::shared::{Axis, Position}; use crate::format; -use rsa_public_encrypt_pkcs1; -use log::{error, debug, warn}; +use crate::protocol::{self, forge, mojang, packet}; +use crate::render; +use crate::resources; +use crate::settings::Stevenkey; +use crate::shared::{Axis, Position}; +use crate::types::hash::FNVHash; +use crate::types::Gamemode; +use crate::world; +use crate::world::block; use base64; +use cgmath::prelude::*; +use log::{debug, error, warn}; +use rand::{self, Rng}; +use rsa_public_encrypt_pkcs1; use serde_json; +use std::collections::HashMap; +use std::hash::BuildHasherDefault; +use std::sync::mpsc; +use std::sync::{Arc, RwLock}; +use std::thread; -mod sun; pub mod plugin_messages; +mod sun; pub mod target; pub struct Server { @@ -70,7 +70,6 @@ pub struct Server { pub rotation: ecs::Key, target_rotation: ecs::Key, // - pub player: Option, entity_map: HashMap>, players: HashMap>, @@ -106,19 +105,24 @@ macro_rules! handle_packet { } impl Server { - - pub fn connect(resources: Arc>, profile: mojang::Profile, address: &str, protocol_version: i32, forge_mods: Vec) -> Result { + pub fn connect( + resources: Arc>, + profile: mojang::Profile, + address: &str, + protocol_version: i32, + forge_mods: Vec, + ) -> Result { let mut conn = protocol::Conn::new(address, protocol_version)?; let tag = if forge_mods.len() != 0 { "\0FML\0" } else { "" }; let host = conn.host.clone() + tag; let port = conn.port; conn.write_packet(protocol::packet::handshake::serverbound::Handshake { - protocol_version: protocol::VarInt(protocol_version), - host, - port, - next: protocol::VarInt(2), - })?; + protocol_version: protocol::VarInt(protocol_version), + host, + port, + next: protocol::VarInt(2), + })?; conn.state = protocol::State::Login; conn.write_packet(protocol::packet::login::serverbound::LoginStart { username: profile.username.clone(), @@ -130,19 +134,19 @@ impl Server { match conn.read_packet()? { protocol::packet::Packet::SetInitialCompression(val) => { conn.set_compresssion(val.threshold.0); - }, + } protocol::packet::Packet::EncryptionRequest(val) => { server_id = Rc::new(val.server_id); public_key = Rc::new(val.public_key.data); verify_token = Rc::new(val.verify_token.data); break; - }, + } protocol::packet::Packet::EncryptionRequest_i16(val) => { server_id = Rc::new(val.server_id); public_key = Rc::new(val.public_key.data); verify_token = Rc::new(val.verify_token.data); break; - }, + } protocol::packet::Packet::LoginSuccess(val) => { warn!("Server is running in offline mode"); debug!("Login: {} {}", val.username, val.uuid); @@ -151,9 +155,18 @@ impl Server { read.state = protocol::State::Play; write.state = protocol::State::Play; let rx = Self::spawn_reader(read); - return Ok(Server::new(protocol_version, forge_mods, protocol::UUID::from_str(&val.uuid), resources, Some(write), Some(rx))); + return Ok(Server::new( + protocol_version, + forge_mods, + protocol::UUID::from_str(&val.uuid), + resources, + Some(write), + Some(rx), + )); + } + protocol::packet::Packet::LoginDisconnect(val) => { + return Err(protocol::Error::Disconnect(val.reason)) } - protocol::packet::Packet::LoginDisconnect(val) => return Err(protocol::Error::Disconnect(val.reason)), val => return Err(protocol::Error::Err(format!("Wrong packet: {:?}", val))), }; } @@ -176,10 +189,12 @@ impl Server { verify_token: protocol::LenPrefixedBytes::new(token_e), })?; } else { - conn.write_packet(protocol::packet::login::serverbound::EncryptionResponse_i16 { - shared_secret: protocol::LenPrefixedBytes::new(shared_e), - verify_token: protocol::LenPrefixedBytes::new(token_e), - })?; + conn.write_packet( + protocol::packet::login::serverbound::EncryptionResponse_i16 { + shared_secret: protocol::LenPrefixedBytes::new(shared_e), + verify_token: protocol::LenPrefixedBytes::new(token_e), + }, + )?; } let mut read = conn.clone(); @@ -190,72 +205,134 @@ impl Server { let uuid; loop { - match read.read_packet()? { - protocol::packet::Packet::SetInitialCompression(val) => { - read.set_compresssion(val.threshold.0); - write.set_compresssion(val.threshold.0); - } - protocol::packet::Packet::LoginSuccess(val) => { - debug!("Login: {} {}", val.username, val.uuid); - uuid = val.uuid; - read.state = protocol::State::Play; - write.state = protocol::State::Play; - break; - } - protocol::packet::Packet::LoginDisconnect(val) => return Err(protocol::Error::Disconnect(val.reason)), - val => return Err(protocol::Error::Err(format!("Wrong packet: {:?}", val))), - } + match read.read_packet()? { + protocol::packet::Packet::SetInitialCompression(val) => { + read.set_compresssion(val.threshold.0); + write.set_compresssion(val.threshold.0); + } + protocol::packet::Packet::LoginSuccess(val) => { + debug!("Login: {} {}", val.username, val.uuid); + uuid = val.uuid; + read.state = protocol::State::Play; + write.state = protocol::State::Play; + break; + } + protocol::packet::Packet::LoginDisconnect(val) => { + return Err(protocol::Error::Disconnect(val.reason)) + } + val => return Err(protocol::Error::Err(format!("Wrong packet: {:?}", val))), + } } let rx = Self::spawn_reader(read); - Ok(Server::new(protocol_version, forge_mods, protocol::UUID::from_str(&uuid), resources, Some(write), Some(rx))) + Ok(Server::new( + protocol_version, + forge_mods, + protocol::UUID::from_str(&uuid), + resources, + Some(write), + Some(rx), + )) } - fn spawn_reader(mut read: protocol::Conn) -> mpsc::Receiver> { + fn spawn_reader( + mut read: protocol::Conn, + ) -> mpsc::Receiver> { let (tx, rx) = mpsc::channel(); - thread::spawn(move || { - loop { - let pck = read.read_packet(); - let was_error = pck.is_err(); - if let Err(_) = tx.send(pck) { - return; - } - if was_error { - return; - } + thread::spawn(move || loop { + let pck = read.read_packet(); + let was_error = pck.is_err(); + if let Err(_) = tx.send(pck) { + return; + } + if was_error { + return; } }); rx } pub fn dummy_server(resources: Arc>) -> Server { - let mut server = Server::new(protocol::SUPPORTED_PROTOCOLS[0], vec![], protocol::UUID::default(), resources, None, None); + let mut server = Server::new( + protocol::SUPPORTED_PROTOCOLS[0], + vec![], + protocol::UUID::default(), + resources, + None, + None, + ); let mut rng = rand::thread_rng(); - for x in -7*16 .. 7*16 { - for z in -7*16 .. 7*16 { + for x in -7 * 16..7 * 16 { + for z in -7 * 16..7 * 16 { let h = 5 + (6.0 * (x as f64 / 16.0).cos() * (z as f64 / 16.0).sin()) as i32; - for y in 0 .. h { - server.world.set_block(Position::new(x, y, z), block::Dirt{ snowy: false, variant: block::DirtVariant::Normal }); + for y in 0..h { + server.world.set_block( + Position::new(x, y, z), + block::Dirt { + snowy: false, + variant: block::DirtVariant::Normal, + }, + ); } - server.world.set_block(Position::new(x, h, z), block::Grass{ snowy: false }); + server + .world + .set_block(Position::new(x, h, z), block::Grass { snowy: false }); - if x*x + z*z > 16*16 && rng.gen_bool(1.0 / 80.0) { - for i in 0 .. 5 { - server.world.set_block(Position::new(x, h + 1 + i, z), block::Log{ axis: Axis::Y, variant: block::TreeVariant::Oak }); + if x * x + z * z > 16 * 16 && rng.gen_bool(1.0 / 80.0) { + for i in 0..5 { + server.world.set_block( + Position::new(x, h + 1 + i, z), + block::Log { + axis: Axis::Y, + variant: block::TreeVariant::Oak, + }, + ); } - for xx in -2 .. 3 { - for zz in -2 .. 3 { + for xx in -2..3 { + for zz in -2..3 { if xx == 0 && z == 0 { continue; } - server.world.set_block(Position::new(x + xx, h + 3, z + zz), block::Leaves{ variant: block::TreeVariant::Oak, check_decay: false, decayable: false, distance: 1 }); - server.world.set_block(Position::new(x + xx, h + 4, z + zz), block::Leaves{ variant: block::TreeVariant::Oak, check_decay: false, decayable: false, distance: 1 }); + server.world.set_block( + Position::new(x + xx, h + 3, z + zz), + block::Leaves { + variant: block::TreeVariant::Oak, + check_decay: false, + decayable: false, + distance: 1, + }, + ); + server.world.set_block( + Position::new(x + xx, h + 4, z + zz), + block::Leaves { + variant: block::TreeVariant::Oak, + check_decay: false, + decayable: false, + distance: 1, + }, + ); if xx.abs() <= 1 && zz.abs() <= 1 { - server.world.set_block(Position::new(x + xx, h + 5, z + zz), block::Leaves{ variant: block::TreeVariant::Oak, check_decay: false, decayable: false, distance: 1 }); + server.world.set_block( + Position::new(x + xx, h + 5, z + zz), + block::Leaves { + variant: block::TreeVariant::Oak, + check_decay: false, + decayable: false, + distance: 1, + }, + ); } if xx * xx + zz * zz <= 1 { - server.world.set_block(Position::new(x + xx, h + 6, z + zz), block::Leaves{ variant: block::TreeVariant::Oak, check_decay: false, decayable: false, distance: 1 }); + server.world.set_block( + Position::new(x + xx, h + 6, z + zz), + block::Leaves { + variant: block::TreeVariant::Oak, + check_decay: false, + decayable: false, + distance: 1, + }, + ); } } } @@ -270,7 +347,8 @@ impl Server { forge_mods: Vec, uuid: protocol::UUID, resources: Arc>, - conn: Option, read_queue: Option>> + conn: Option, + read_queue: Option>>, ) -> Server { let mut entities = ecs::Manager::new(); entity::add_systems(&mut entities); @@ -309,7 +387,6 @@ impl Server { rotation: entities.get_key(), target_rotation: entities.get_key(), // - entities, player: None, entity_map: HashMap::with_hasher(BuildHasherDefault::default()), @@ -351,7 +428,8 @@ impl Server { if let Some(player) = self.player { let position = self.entities.get_component(player, self.position).unwrap(); let rotation = self.entities.get_component(player, self.rotation).unwrap(); - renderer.camera.pos = cgmath::Point3::from_vec(position.position + cgmath::Vector3::new(0.0, 1.62, 0.0)); + renderer.camera.pos = + cgmath::Point3::from_vec(position.position + cgmath::Vector3::new(0.0, 1.62, 0.0)); renderer.camera.yaw = rotation.yaw; renderer.camera.pitch = rotation.pitch; } @@ -372,7 +450,13 @@ impl Server { self.world.tick(&mut self.entities); if self.player.is_some() { - if let Some((pos, bl, _, _)) = target::trace_ray(&self.world, 4.0, renderer.camera.pos.to_vec(), renderer.view_vector.cast().unwrap(), target::test_block) { + if let Some((pos, bl, _, _)) = target::trace_ray( + &self.world, + 4.0, + renderer.camera.pos.to_vec(), + renderer.view_vector.cast().unwrap(), + target::test_block, + ) { self.target_info.update(renderer, pos, bl); } else { self.target_info.clear(renderer); @@ -385,14 +469,16 @@ impl Server { fn entity_tick(&mut self, renderer: &mut render::Renderer, delta: f64) { let world_entity = self.entities.get_world(); // Update the game's state for entities to read - self.entities.get_component_mut(world_entity, self.game_info) - .unwrap().delta = delta; + self.entities + .get_component_mut(world_entity, self.game_info) + .unwrap() + .delta = delta; // Packets modify entities so need to handled here if let Some(rx) = self.read_queue.take() { while let Ok(pck) = rx.try_recv() { match pck { - Ok(pck) => handle_packet!{ + Ok(pck) => handle_packet! { self pck { PluginMessageClientbound_i16 => on_plugin_message_clientbound_i16, PluginMessageClientbound => on_plugin_message_clientbound_1, @@ -464,7 +550,8 @@ impl Server { } } - if self.is_connected() || self.just_disconnected { // Allow an extra tick when disconnected to clean up + if self.is_connected() || self.just_disconnected { + // Allow an extra tick when disconnected to clean up self.just_disconnected = false; self.entity_tick_timer += delta; while self.entity_tick_timer >= 3.0 { @@ -528,9 +615,18 @@ impl Server { pub fn minecraft_tick(&mut self) { use std::f32::consts::PI; if let Some(player) = self.player { - 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 position = self.entities.get_component(player, self.target_position).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 position = self + .entities + .get_component(player, self.target_position) + .unwrap(); let rotation = self.entities.get_component(player, self.rotation).unwrap(); // Force the server to know when touched the ground @@ -572,7 +668,10 @@ impl Server { pub fn key_press(&mut self, down: bool, key: Stevenkey) { if let Some(player) = self.player { - if let Some(movement) = self.entities.get_component_mut(player, self.player_movement) { + if let Some(movement) = self + .entities + .get_component_mut(player, self.player_movement) + { movement.pressed_keys.insert(key, down); } } @@ -581,7 +680,13 @@ impl Server { pub fn on_right_click(&mut self, renderer: &mut render::Renderer) { use crate::shared::Direction; if self.player.is_some() { - if let Some((pos, _, face, at)) = target::trace_ray(&self.world, 4.0, renderer.camera.pos.to_vec(), renderer.view_vector.cast().unwrap(), target::test_block) { + if let Some((pos, _, face, at)) = target::trace_ray( + &self.world, + 4.0, + renderer.camera.pos.to_vec(), + renderer.view_vector.cast().unwrap(), + target::test_block, + ) { if self.protocol_version >= 315 { self.write_packet(packet::play::serverbound::PlayerBlockPlacement_f32 { location: pos, @@ -634,24 +739,26 @@ impl Server { cursor_z: (at.z * 16.0) as u8, }); } else { - self.write_packet(packet::play::serverbound::PlayerBlockPlacement_u8_Item_u8y { - x: pos.x, - y: pos.y as u8, - z: pos.x, - face: match face { - Direction::Down => 0, - Direction::Up => 1, - Direction::North => 2, - Direction::South => 3, - Direction::West => 4, - Direction::East => 5, - _ => unreachable!(), + self.write_packet( + packet::play::serverbound::PlayerBlockPlacement_u8_Item_u8y { + x: pos.x, + y: pos.y as u8, + z: pos.x, + face: match face { + Direction::Down => 0, + Direction::Up => 1, + Direction::North => 2, + Direction::South => 3, + Direction::West => 4, + Direction::East => 5, + _ => unreachable!(), + }, + hand: None, + cursor_x: (at.x * 16.0) as u8, + cursor_y: (at.y * 16.0) as u8, + cursor_z: (at.z * 16.0) as u8, }, - hand: None, - cursor_x: (at.x * 16.0) as u8, - cursor_y: (at.y * 16.0) as u8, - cursor_z: (at.z * 16.0) as u8, - }); + ); } } } @@ -661,72 +768,121 @@ impl Server { let _ = self.conn.as_mut().unwrap().write_packet(p); // TODO handle errors } - fn on_keep_alive_i64(&mut self, keep_alive: packet::play::clientbound::KeepAliveClientbound_i64) { + fn on_keep_alive_i64( + &mut self, + keep_alive: packet::play::clientbound::KeepAliveClientbound_i64, + ) { self.write_packet(packet::play::serverbound::KeepAliveServerbound_i64 { id: keep_alive.id, }); } - fn on_keep_alive_varint(&mut self, keep_alive: packet::play::clientbound::KeepAliveClientbound_VarInt) { + fn on_keep_alive_varint( + &mut self, + keep_alive: packet::play::clientbound::KeepAliveClientbound_VarInt, + ) { self.write_packet(packet::play::serverbound::KeepAliveServerbound_VarInt { id: keep_alive.id, }); } - fn on_keep_alive_i32(&mut self, keep_alive: packet::play::clientbound::KeepAliveClientbound_i32) { + fn on_keep_alive_i32( + &mut self, + keep_alive: packet::play::clientbound::KeepAliveClientbound_i32, + ) { self.write_packet(packet::play::serverbound::KeepAliveServerbound_i32 { id: keep_alive.id, }); } - fn on_plugin_message_clientbound_i16(&mut self, msg: packet::play::clientbound::PluginMessageClientbound_i16) { + fn on_plugin_message_clientbound_i16( + &mut self, + msg: packet::play::clientbound::PluginMessageClientbound_i16, + ) { self.on_plugin_message_clientbound(&msg.channel, msg.data.data.as_slice()) } - fn on_plugin_message_clientbound_1(&mut self, msg: packet::play::clientbound::PluginMessageClientbound) { + fn on_plugin_message_clientbound_1( + &mut self, + msg: packet::play::clientbound::PluginMessageClientbound, + ) { self.on_plugin_message_clientbound(&msg.channel, &msg.data) } fn on_plugin_message_clientbound(&mut self, channel: &str, data: &[u8]) { if protocol::is_network_debug() { - debug!("Received plugin message: channel={}, data={:?}", channel, data); + debug!( + "Received plugin message: channel={}, data={:?}", + channel, data + ); } match channel { - // TODO: "REGISTER" => + // TODO: "REGISTER" => // TODO: "UNREGISTER" => "FML|HS" => { - let msg = crate::protocol::Serializable::read_from(&mut std::io::Cursor::new(data)).unwrap(); + let msg = crate::protocol::Serializable::read_from(&mut std::io::Cursor::new(data)) + .unwrap(); //debug!("FML|HS msg={:?}", msg); use forge::FmlHs::*; use forge::Phase::*; match msg { - ServerHello { fml_protocol_version, override_dimension } => { - debug!("Received FML|HS ServerHello {} {:?}", fml_protocol_version, override_dimension); + ServerHello { + fml_protocol_version, + override_dimension, + } => { + debug!( + "Received FML|HS ServerHello {} {:?}", + fml_protocol_version, override_dimension + ); - self.write_plugin_message("REGISTER", "FML|HS\0FML\0FML|MP\0FML\0FORGE".as_bytes()); - self.write_fmlhs_plugin_message(&ClientHello { fml_protocol_version }); + self.write_plugin_message( + "REGISTER", + "FML|HS\0FML\0FML|MP\0FML\0FORGE".as_bytes(), + ); + self.write_fmlhs_plugin_message(&ClientHello { + fml_protocol_version, + }); // Send stashed mods list received from ping packet, client matching server - let mods = crate::protocol::LenPrefixed::::new(self.forge_mods.clone()); + let mods = crate::protocol::LenPrefixed::< + crate::protocol::VarInt, + forge::ForgeMod, + >::new(self.forge_mods.clone()); self.write_fmlhs_plugin_message(&ModList { mods }); - }, + } ModList { mods } => { debug!("Received FML|HS ModList: {:?}", mods); - self.write_fmlhs_plugin_message(&HandshakeAck { phase: WaitingServerData }); - }, - ModIdData { mappings, block_substitutions: _, item_substitutions: _ } => { + self.write_fmlhs_plugin_message(&HandshakeAck { + phase: WaitingServerData, + }); + } + ModIdData { + mappings, + block_substitutions: _, + item_substitutions: _, + } => { debug!("Received FML|HS ModIdData"); for m in mappings.data { let (namespace, name) = m.name.split_at(1); if namespace == protocol::forge::BLOCK_NAMESPACE { - self.world.modded_block_ids.insert(m.id.0 as usize, name.to_string()); + self.world + .modded_block_ids + .insert(m.id.0 as usize, name.to_string()); } } - self.write_fmlhs_plugin_message(&HandshakeAck { phase: WaitingServerComplete }); - }, - RegistryData { has_more, name, ids, substitutions: _, dummies: _ } => { + self.write_fmlhs_plugin_message(&HandshakeAck { + phase: WaitingServerComplete, + }); + } + RegistryData { + has_more, + name, + ids, + substitutions: _, + dummies: _, + } => { debug!("Received FML|HS RegistryData for {}", name); if name == "minecraft:blocks" { for m in ids.data { @@ -734,24 +890,26 @@ impl Server { } } if !has_more { - self.write_fmlhs_plugin_message(&HandshakeAck { phase: WaitingServerComplete }); + self.write_fmlhs_plugin_message(&HandshakeAck { + phase: WaitingServerComplete, + }); } - }, - HandshakeAck { phase } => { - match phase { - WaitingCAck => { - self.write_fmlhs_plugin_message(&HandshakeAck { phase: PendingComplete }); - }, - Complete => { - debug!("FML|HS handshake complete!"); - }, - _ => unimplemented!(), + } + HandshakeAck { phase } => match phase { + WaitingCAck => { + self.write_fmlhs_plugin_message(&HandshakeAck { + phase: PendingComplete, + }); } + Complete => { + debug!("FML|HS handshake complete!"); + } + _ => unimplemented!(), }, _ => (), } } - _ => () + _ => (), } } @@ -766,7 +924,10 @@ impl Server { fn write_plugin_message(&mut self, channel: &str, data: &[u8]) { if protocol::is_network_debug() { - debug!("Sending plugin message: channel={}, data={:?}", channel, data); + debug!( + "Sending plugin message: channel={}, data={:?}", + channel, data + ); } if self.protocol_version >= 47 { self.write_packet(packet::play::serverbound::PluginMessageServerbound { @@ -781,11 +942,17 @@ impl Server { } } - fn on_game_join_hashedseed_respawn(&mut self, join: packet::play::clientbound::JoinGame_HashedSeed_Respawn) { + fn on_game_join_hashedseed_respawn( + &mut self, + join: packet::play::clientbound::JoinGame_HashedSeed_Respawn, + ) { self.on_game_join(join.gamemode, join.entity_id) } - fn on_game_join_i32_viewdistance(&mut self, join: packet::play::clientbound::JoinGame_i32_ViewDistance) { + fn on_game_join_i32_viewdistance( + &mut self, + join: packet::play::clientbound::JoinGame_i32_ViewDistance, + ) { self.on_game_join(join.gamemode, join.entity_id) } @@ -801,25 +968,33 @@ impl Server { self.on_game_join(join.gamemode, join.entity_id) } - fn on_game_join(&mut self, gamemode: u8, entity_id: i32) { let gamemode = Gamemode::from_int((gamemode & 0x7) as i32); let player = entity::player::create_local(&mut self.entities); if let Some(info) = self.players.get(&self.uuid) { - let model = self.entities.get_component_mut_direct::(player).unwrap(); + let model = self + .entities + .get_component_mut_direct::(player) + .unwrap(); model.set_skin(info.skin_url.clone()); } - *self.entities.get_component_mut(player, self.gamemode).unwrap() = gamemode; + *self + .entities + .get_component_mut(player, self.gamemode) + .unwrap() = gamemode; // TODO: Temp - self.entities.get_component_mut(player, self.player_movement).unwrap().flying = gamemode.can_fly(); + self.entities + .get_component_mut(player, self.player_movement) + .unwrap() + .flying = gamemode.can_fly(); self.entity_map.insert(entity_id, player); self.player = Some(player); // Let the server know who we are let brand = plugin_messages::Brand { - brand: "Steven".into(), - }; + brand: "Steven".into(), + }; // TODO: refactor with write_plugin_message if self.protocol_version >= 47 { self.write_packet(brand.as_message()); @@ -841,9 +1016,15 @@ impl Server { let gamemode = Gamemode::from_int((gamemode_u8 & 0x7) as i32); if let Some(player) = self.player { - *self.entities.get_component_mut(player, self.gamemode).unwrap() = gamemode; + *self + .entities + .get_component_mut(player, self.gamemode) + .unwrap() = gamemode; // TODO: Temp - self.entities.get_component_mut(player, self.player_movement).unwrap().flying = gamemode.can_fly(); + self.entities + .get_component_mut(player, self.player_movement) + .unwrap() + .flying = gamemode.can_fly(); } } @@ -866,9 +1047,15 @@ impl Server { if game_state.reason == 3 { if let Some(player) = self.player { let gamemode = Gamemode::from_int(game_state.value as i32); - *self.entities.get_component_mut(player, self.gamemode).unwrap() = gamemode; + *self + .entities + .get_component_mut(player, self.gamemode) + .unwrap() = gamemode; // TODO: Temp - self.entities.get_component_mut(player, self.player_movement).unwrap().flying = gamemode.can_fly(); + self.entities + .get_component_mut(player, self.player_movement) + .unwrap() + .flying = gamemode.can_fly(); } } } @@ -881,7 +1068,10 @@ impl Server { } } - fn on_entity_destroy_u8(&mut self, entity_destroy: packet::play::clientbound::EntityDestroy_u8) { + fn on_entity_destroy_u8( + &mut self, + entity_destroy: packet::play::clientbound::EntityDestroy_u8, + ) { for id in entity_destroy.entity_ids.data { if let Some(entity) = self.entity_map.remove(&id) { self.entities.remove_entity(entity); @@ -889,25 +1079,72 @@ impl Server { } } - fn on_entity_teleport_f64(&mut self, entity_telport: packet::play::clientbound::EntityTeleport_f64) { - self.on_entity_teleport(entity_telport.entity_id.0, entity_telport.x, entity_telport.y, entity_telport.z, entity_telport.yaw as f64, entity_telport.pitch as f64, entity_telport.on_ground) + fn on_entity_teleport_f64( + &mut self, + entity_telport: packet::play::clientbound::EntityTeleport_f64, + ) { + self.on_entity_teleport( + entity_telport.entity_id.0, + entity_telport.x, + entity_telport.y, + entity_telport.z, + entity_telport.yaw as f64, + entity_telport.pitch as f64, + entity_telport.on_ground, + ) } - fn on_entity_teleport_i32(&mut self, entity_telport: packet::play::clientbound::EntityTeleport_i32) { - self.on_entity_teleport(entity_telport.entity_id.0, f64::from(entity_telport.x), f64::from(entity_telport.y), f64::from(entity_telport.z), entity_telport.yaw as f64, entity_telport.pitch as f64, entity_telport.on_ground) + fn on_entity_teleport_i32( + &mut self, + entity_telport: packet::play::clientbound::EntityTeleport_i32, + ) { + self.on_entity_teleport( + entity_telport.entity_id.0, + f64::from(entity_telport.x), + f64::from(entity_telport.y), + f64::from(entity_telport.z), + entity_telport.yaw as f64, + entity_telport.pitch as f64, + entity_telport.on_ground, + ) } - fn on_entity_teleport_i32_i32_noground(&mut self, entity_telport: packet::play::clientbound::EntityTeleport_i32_i32_NoGround) { + fn on_entity_teleport_i32_i32_noground( + &mut self, + entity_telport: packet::play::clientbound::EntityTeleport_i32_i32_NoGround, + ) { let on_ground = true; // TODO: how is this supposed to be set? (for 1.7) - self.on_entity_teleport(entity_telport.entity_id, f64::from(entity_telport.x), f64::from(entity_telport.y), f64::from(entity_telport.z), entity_telport.yaw as f64, entity_telport.pitch as f64, on_ground) + self.on_entity_teleport( + entity_telport.entity_id, + f64::from(entity_telport.x), + f64::from(entity_telport.y), + f64::from(entity_telport.z), + entity_telport.yaw as f64, + entity_telport.pitch as f64, + on_ground, + ) } - - fn on_entity_teleport(&mut self, entity_id: i32, x: f64, y: f64, z: f64, yaw: f64, pitch: f64, _on_ground: bool) { + fn on_entity_teleport( + &mut self, + entity_id: i32, + x: f64, + y: f64, + z: f64, + yaw: f64, + pitch: f64, + _on_ground: bool, + ) { use std::f64::consts::PI; if let Some(entity) = self.entity_map.get(&entity_id) { - let target_position = self.entities.get_component_mut(*entity, self.target_position).unwrap(); - let target_rotation = self.entities.get_component_mut(*entity, self.target_rotation).unwrap(); + let target_position = self + .entities + .get_component_mut(*entity, self.target_position) + .unwrap(); + let target_rotation = self + .entities + .get_component_mut(*entity, self.target_rotation) + .unwrap(); target_position.position.x = x; target_position.position.y = y; target_position.position.z = z; @@ -917,21 +1154,41 @@ impl Server { } fn on_entity_move_i16(&mut self, m: packet::play::clientbound::EntityMove_i16) { - self.on_entity_move(m.entity_id.0, f64::from(m.delta_x), f64::from(m.delta_y), f64::from(m.delta_z)) + self.on_entity_move( + m.entity_id.0, + f64::from(m.delta_x), + f64::from(m.delta_y), + f64::from(m.delta_z), + ) } fn on_entity_move_i8(&mut self, m: packet::play::clientbound::EntityMove_i8) { - self.on_entity_move(m.entity_id.0, f64::from(m.delta_x), f64::from(m.delta_y), f64::from(m.delta_z)) + self.on_entity_move( + m.entity_id.0, + f64::from(m.delta_x), + f64::from(m.delta_y), + f64::from(m.delta_z), + ) } - fn on_entity_move_i8_i32_noground(&mut self, m: packet::play::clientbound::EntityMove_i8_i32_NoGround) { - self.on_entity_move(m.entity_id, f64::from(m.delta_x), f64::from(m.delta_y), f64::from(m.delta_z)) + fn on_entity_move_i8_i32_noground( + &mut self, + m: packet::play::clientbound::EntityMove_i8_i32_NoGround, + ) { + self.on_entity_move( + m.entity_id, + f64::from(m.delta_x), + f64::from(m.delta_y), + f64::from(m.delta_z), + ) } - fn on_entity_move(&mut self, entity_id: i32, delta_x: f64, delta_y: f64, delta_z: f64) { if let Some(entity) = self.entity_map.get(&entity_id) { - let position = self.entities.get_component_mut(*entity, self.target_position).unwrap(); + let position = self + .entities + .get_component_mut(*entity, self.target_position) + .unwrap(); position.position.x += delta_x; position.position.y += delta_y; position.position.z += delta_z; @@ -941,7 +1198,10 @@ impl Server { fn on_entity_look(&mut self, entity_id: i32, yaw: f64, pitch: f64) { use std::f64::consts::PI; if let Some(entity) = self.entity_map.get(&entity_id) { - let rotation = self.entities.get_component_mut(*entity, self.target_rotation).unwrap(); + let rotation = self + .entities + .get_component_mut(*entity, self.target_rotation) + .unwrap(); rotation.yaw = -(yaw / 256.0) * PI * 2.0; rotation.pitch = -(pitch / 256.0) * PI * 2.0; } @@ -951,33 +1211,74 @@ impl Server { self.on_entity_look(look.entity_id.0, look.yaw as f64, look.pitch as f64) } - fn on_entity_look_i32_noground(&mut self, look: packet::play::clientbound::EntityLook_i32_NoGround) { + fn on_entity_look_i32_noground( + &mut self, + look: packet::play::clientbound::EntityLook_i32_NoGround, + ) { self.on_entity_look(look.entity_id, look.yaw as f64, look.pitch as f64) } - fn on_entity_look_and_move_i16(&mut self, lookmove: packet::play::clientbound::EntityLookAndMove_i16) { - self.on_entity_look_and_move(lookmove.entity_id.0, - f64::from(lookmove.delta_x), f64::from(lookmove.delta_y), f64::from(lookmove.delta_z), - lookmove.yaw as f64, lookmove.pitch as f64) + fn on_entity_look_and_move_i16( + &mut self, + lookmove: packet::play::clientbound::EntityLookAndMove_i16, + ) { + self.on_entity_look_and_move( + lookmove.entity_id.0, + f64::from(lookmove.delta_x), + f64::from(lookmove.delta_y), + f64::from(lookmove.delta_z), + lookmove.yaw as f64, + lookmove.pitch as f64, + ) } - fn on_entity_look_and_move_i8(&mut self, lookmove: packet::play::clientbound::EntityLookAndMove_i8) { - self.on_entity_look_and_move(lookmove.entity_id.0, - f64::from(lookmove.delta_x), f64::from(lookmove.delta_y), f64::from(lookmove.delta_z), - lookmove.yaw as f64, lookmove.pitch as f64) + fn on_entity_look_and_move_i8( + &mut self, + lookmove: packet::play::clientbound::EntityLookAndMove_i8, + ) { + self.on_entity_look_and_move( + lookmove.entity_id.0, + f64::from(lookmove.delta_x), + f64::from(lookmove.delta_y), + f64::from(lookmove.delta_z), + lookmove.yaw as f64, + lookmove.pitch as f64, + ) } - fn on_entity_look_and_move_i8_i32_noground(&mut self, lookmove: packet::play::clientbound::EntityLookAndMove_i8_i32_NoGround) { - self.on_entity_look_and_move(lookmove.entity_id, - f64::from(lookmove.delta_x), f64::from(lookmove.delta_y), f64::from(lookmove.delta_z), - lookmove.yaw as f64, lookmove.pitch as f64) + fn on_entity_look_and_move_i8_i32_noground( + &mut self, + lookmove: packet::play::clientbound::EntityLookAndMove_i8_i32_NoGround, + ) { + self.on_entity_look_and_move( + lookmove.entity_id, + f64::from(lookmove.delta_x), + f64::from(lookmove.delta_y), + f64::from(lookmove.delta_z), + lookmove.yaw as f64, + lookmove.pitch as f64, + ) } - fn on_entity_look_and_move(&mut self, entity_id: i32, delta_x: f64, delta_y: f64, delta_z: f64, yaw: f64, pitch: f64) { + fn on_entity_look_and_move( + &mut self, + entity_id: i32, + delta_x: f64, + delta_y: f64, + delta_z: f64, + yaw: f64, + pitch: f64, + ) { use std::f64::consts::PI; if let Some(entity) = self.entity_map.get(&entity_id) { - let position = self.entities.get_component_mut(*entity, self.target_position).unwrap(); - let rotation = self.entities.get_component_mut(*entity, self.target_rotation).unwrap(); + let position = self + .entities + .get_component_mut(*entity, self.target_position) + .unwrap(); + let rotation = self + .entities + .get_component_mut(*entity, self.target_rotation) + .unwrap(); position.position.x += delta_x; position.position.y += delta_y; position.position.z += delta_z; @@ -987,31 +1288,93 @@ impl Server { } fn on_player_spawn_f64(&mut self, spawn: packet::play::clientbound::SpawnPlayer_f64) { - self.on_player_spawn(spawn.entity_id.0, spawn.uuid, spawn.x, spawn.y, spawn.z, spawn.yaw as f64, spawn.pitch as f64) + self.on_player_spawn( + spawn.entity_id.0, + spawn.uuid, + spawn.x, + spawn.y, + spawn.z, + spawn.yaw as f64, + spawn.pitch as f64, + ) } fn on_player_spawn_i32(&mut self, spawn: packet::play::clientbound::SpawnPlayer_i32) { - self.on_player_spawn(spawn.entity_id.0, spawn.uuid, f64::from(spawn.x), f64::from(spawn.y), f64::from(spawn.z), spawn.yaw as f64, spawn.pitch as f64) + self.on_player_spawn( + spawn.entity_id.0, + spawn.uuid, + f64::from(spawn.x), + f64::from(spawn.y), + f64::from(spawn.z), + spawn.yaw as f64, + spawn.pitch as f64, + ) } - fn on_player_spawn_i32_helditem(&mut self, spawn: packet::play::clientbound::SpawnPlayer_i32_HeldItem) { - self.on_player_spawn(spawn.entity_id.0, spawn.uuid, f64::from(spawn.x), f64::from(spawn.y), f64::from(spawn.z), spawn.yaw as f64, spawn.pitch as f64) + fn on_player_spawn_i32_helditem( + &mut self, + spawn: packet::play::clientbound::SpawnPlayer_i32_HeldItem, + ) { + self.on_player_spawn( + spawn.entity_id.0, + spawn.uuid, + f64::from(spawn.x), + f64::from(spawn.y), + f64::from(spawn.z), + spawn.yaw as f64, + spawn.pitch as f64, + ) } - fn on_player_spawn_i32_helditem_string(&mut self, spawn: packet::play::clientbound::SpawnPlayer_i32_HeldItem_String) { - self.on_player_spawn(spawn.entity_id.0, protocol::UUID::from_str(&spawn.uuid), f64::from(spawn.x), f64::from(spawn.y), f64::from(spawn.z), spawn.yaw as f64, spawn.pitch as f64) + fn on_player_spawn_i32_helditem_string( + &mut self, + spawn: packet::play::clientbound::SpawnPlayer_i32_HeldItem_String, + ) { + self.on_player_spawn( + spawn.entity_id.0, + protocol::UUID::from_str(&spawn.uuid), + f64::from(spawn.x), + f64::from(spawn.y), + f64::from(spawn.z), + spawn.yaw as f64, + spawn.pitch as f64, + ) } - fn on_player_spawn(&mut self, entity_id: i32, uuid: protocol::UUID, x: f64, y: f64, z: f64, pitch: f64, yaw: f64) { + fn on_player_spawn( + &mut self, + entity_id: i32, + uuid: protocol::UUID, + x: f64, + y: f64, + z: f64, + pitch: f64, + yaw: f64, + ) { use std::f64::consts::PI; if let Some(entity) = self.entity_map.remove(&entity_id) { self.entities.remove_entity(entity); } - let entity = entity::player::create_remote(&mut self.entities, self.players.get(&uuid).map_or("MISSING", |v| &v.name)); - let position = self.entities.get_component_mut(entity, self.position).unwrap(); - let target_position = self.entities.get_component_mut(entity, self.target_position).unwrap(); - let rotation = self.entities.get_component_mut(entity, self.rotation).unwrap(); - let target_rotation = self.entities.get_component_mut(entity, self.target_rotation).unwrap(); + let entity = entity::player::create_remote( + &mut self.entities, + self.players.get(&uuid).map_or("MISSING", |v| &v.name), + ); + let position = self + .entities + .get_component_mut(entity, self.position) + .unwrap(); + let target_position = self + .entities + .get_component_mut(entity, self.target_position) + .unwrap(); + let rotation = self + .entities + .get_component_mut(entity, self.rotation) + .unwrap(); + let target_rotation = self + .entities + .get_component_mut(entity, self.target_rotation) + .unwrap(); position.position.x = x; position.position.y = y; position.position.z = z; @@ -1023,43 +1386,106 @@ impl Server { target_rotation.yaw = rotation.yaw; target_rotation.pitch = rotation.pitch; if let Some(info) = self.players.get(&uuid) { - let model = self.entities.get_component_mut_direct::(entity).unwrap(); + let model = self + .entities + .get_component_mut_direct::(entity) + .unwrap(); model.set_skin(info.skin_url.clone()); } self.entity_map.insert(entity_id, entity); } - fn on_teleport_player_withconfirm(&mut self, teleport: packet::play::clientbound::TeleportPlayer_WithConfirm) { - self.on_teleport_player(teleport.x, teleport.y, teleport.z, teleport.yaw as f64, teleport.pitch as f64, teleport.flags, Some(teleport.teleport_id)) + fn on_teleport_player_withconfirm( + &mut self, + teleport: packet::play::clientbound::TeleportPlayer_WithConfirm, + ) { + self.on_teleport_player( + teleport.x, + teleport.y, + teleport.z, + teleport.yaw as f64, + teleport.pitch as f64, + teleport.flags, + Some(teleport.teleport_id), + ) } - fn on_teleport_player_noconfirm(&mut self, teleport: packet::play::clientbound::TeleportPlayer_NoConfirm) { - self.on_teleport_player(teleport.x, teleport.y, teleport.z, teleport.yaw as f64, teleport.pitch as f64, teleport.flags, None) + fn on_teleport_player_noconfirm( + &mut self, + teleport: packet::play::clientbound::TeleportPlayer_NoConfirm, + ) { + self.on_teleport_player( + teleport.x, + teleport.y, + teleport.z, + teleport.yaw as f64, + teleport.pitch as f64, + teleport.flags, + None, + ) } - fn on_teleport_player_onground(&mut self, teleport: packet::play::clientbound::TeleportPlayer_OnGround) { + fn on_teleport_player_onground( + &mut self, + teleport: packet::play::clientbound::TeleportPlayer_OnGround, + ) { let flags: u8 = 0; // always absolute - self.on_teleport_player(teleport.x, teleport.eyes_y - 1.62, teleport.z, teleport.yaw as f64, teleport.pitch as f64, flags, None) + self.on_teleport_player( + teleport.x, + teleport.eyes_y - 1.62, + teleport.z, + teleport.yaw as f64, + teleport.pitch as f64, + flags, + None, + ) } - fn on_teleport_player(&mut self, x: f64, y: f64, z: f64, yaw: f64, pitch: f64, flags: u8, teleport_id: Option) { + fn on_teleport_player( + &mut self, + x: f64, + y: f64, + z: f64, + yaw: f64, + pitch: f64, + flags: u8, + teleport_id: Option, + ) { use std::f64::consts::PI; if let Some(player) = self.player { - let position = self.entities.get_component_mut(player, self.target_position).unwrap(); - let rotation = self.entities.get_component_mut(player, self.rotation).unwrap(); - let velocity = self.entities.get_component_mut(player, self.velocity).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 velocity = self + .entities + .get_component_mut(player, self.velocity) + .unwrap(); - position.position.x = calculate_relative_teleport(TeleportFlag::RelX, flags, position.position.x, x); - position.position.y = calculate_relative_teleport(TeleportFlag::RelY, flags, position.position.y, y); - position.position.z = calculate_relative_teleport(TeleportFlag::RelZ, flags, position.position.z, z); - rotation.yaw = calculate_relative_teleport(TeleportFlag::RelYaw, flags, rotation.yaw, -yaw as f64 * (PI / 180.0)); + position.position.x = + calculate_relative_teleport(TeleportFlag::RelX, flags, position.position.x, x); + position.position.y = + calculate_relative_teleport(TeleportFlag::RelY, flags, position.position.y, y); + position.position.z = + calculate_relative_teleport(TeleportFlag::RelZ, flags, position.position.z, z); + rotation.yaw = calculate_relative_teleport( + TeleportFlag::RelYaw, + flags, + rotation.yaw, + -yaw as f64 * (PI / 180.0), + ); rotation.pitch = -((calculate_relative_teleport( TeleportFlag::RelPitch, flags, (-rotation.pitch) * (180.0 / PI) + 180.0, - pitch - ) - 180.0) * (PI / 180.0)); + pitch, + ) - 180.0) + * (PI / 180.0)); if (flags & (TeleportFlag::RelX as u8)) == 0 { velocity.velocity.x = 0.0; @@ -1072,21 +1498,23 @@ impl Server { } if let Some(teleport_id) = teleport_id { - self.write_packet(packet::play::serverbound::TeleportConfirm { - teleport_id, - }); + self.write_packet(packet::play::serverbound::TeleportConfirm { teleport_id }); } } } - fn on_block_entity_update(&mut self, block_update: packet::play::clientbound::UpdateBlockEntity) { + fn on_block_entity_update( + &mut self, + block_update: packet::play::clientbound::UpdateBlockEntity, + ) { match block_update.nbt { None => { // NBT is null, so we need to remove the block entity - self.world.add_block_entity_action(world::BlockEntityAction::Remove( - block_update.location, - )); - }, + self.world + .add_block_entity_action(world::BlockEntityAction::Remove( + block_update.location, + )); + } Some(nbt) => { match block_update.action { // TODO: support more block update actions @@ -1098,32 +1526,46 @@ impl Server { //6 => // Banner //7 => // Structure //8 => // Gateway - 9 => { // Sign - let line1 = format::Component::from_string(nbt.1.get("Text1").unwrap().as_str().unwrap()); - let line2 = format::Component::from_string(nbt.1.get("Text2").unwrap().as_str().unwrap()); - let line3 = format::Component::from_string(nbt.1.get("Text3").unwrap().as_str().unwrap()); - let line4 = format::Component::from_string(nbt.1.get("Text4").unwrap().as_str().unwrap()); - self.world.add_block_entity_action(world::BlockEntityAction::UpdateSignText( - block_update.location, - line1, - line2, - line3, - line4, - )); - }, + 9 => { + // Sign + let line1 = format::Component::from_string( + nbt.1.get("Text1").unwrap().as_str().unwrap(), + ); + let line2 = format::Component::from_string( + nbt.1.get("Text2").unwrap().as_str().unwrap(), + ); + let line3 = format::Component::from_string( + nbt.1.get("Text3").unwrap().as_str().unwrap(), + ); + let line4 = format::Component::from_string( + nbt.1.get("Text4").unwrap().as_str().unwrap(), + ); + self.world.add_block_entity_action( + world::BlockEntityAction::UpdateSignText( + block_update.location, + line1, + line2, + line3, + line4, + ), + ); + } //10 => // Unused //11 => // Jigsaw //12 => // Campfire //14 => // Beehive _ => { debug!("Unsupported block entity action: {}", block_update.action); - }, + } } } } } - fn on_block_entity_update_data(&mut self, _block_update: packet::play::clientbound::UpdateBlockEntity_Data) { + fn on_block_entity_update_data( + &mut self, + _block_update: packet::play::clientbound::UpdateBlockEntity_Data, + ) { // TODO: handle UpdateBlockEntity_Data for 1.7, decompress gzipped_nbt } @@ -1132,13 +1574,14 @@ impl Server { format::convert_legacy(&mut update_sign.line2); format::convert_legacy(&mut update_sign.line3); format::convert_legacy(&mut update_sign.line4); - self.world.add_block_entity_action(world::BlockEntityAction::UpdateSignText( - update_sign.location, - update_sign.line1, - update_sign.line2, - update_sign.line3, - update_sign.line4, - )); + self.world + .add_block_entity_action(world::BlockEntityAction::UpdateSignText( + update_sign.location, + update_sign.line1, + update_sign.line2, + update_sign.line3, + update_sign.line4, + )); } fn on_sign_update_u16(&mut self, mut update_sign: packet::play::clientbound::UpdateSign_u16) { @@ -1146,17 +1589,20 @@ impl Server { format::convert_legacy(&mut update_sign.line2); format::convert_legacy(&mut update_sign.line3); format::convert_legacy(&mut update_sign.line4); - self.world.add_block_entity_action(world::BlockEntityAction::UpdateSignText( - Position::new(update_sign.x, update_sign.y as i32, update_sign.z), - update_sign.line1, - update_sign.line2, - update_sign.line3, - update_sign.line4, - )); + self.world + .add_block_entity_action(world::BlockEntityAction::UpdateSignText( + Position::new(update_sign.x, update_sign.y as i32, update_sign.z), + update_sign.line1, + update_sign.line2, + update_sign.line3, + update_sign.line4, + )); } - - fn on_player_info_string(&mut self, _player_info: packet::play::clientbound::PlayerInfo_String) { + fn on_player_info_string( + &mut self, + _player_info: packet::play::clientbound::PlayerInfo_String, + ) { // TODO: support PlayerInfo_String for 1.7 } @@ -1164,7 +1610,14 @@ impl Server { use crate::protocol::packet::PlayerDetail::*; for detail in player_info.inner.players { match detail { - Add { name, uuid, properties, display, gamemode, ping} => { + Add { + name, + uuid, + properties, + display, + gamemode, + ping, + } => { let info = self.players.entry(uuid.clone()).or_insert(PlayerInfo { name: name.clone(), uuid, @@ -1195,16 +1648,20 @@ impl Server { Err(err) => { error!("Failed to decode skin blob, {:?}", err); continue; - }, + } }; - let skin_blob: serde_json::Value = match serde_json::from_slice(&skin_blob) { + let skin_blob: serde_json::Value = match serde_json::from_slice(&skin_blob) + { Ok(val) => val, Err(err) => { error!("Failed to parse skin blob, {:?}", err); continue; - }, + } }; - if let Some(skin_url) = skin_blob.pointer("/textures/SKIN/url").and_then(|v| v.as_str()) { + if let Some(skin_url) = skin_blob + .pointer("/textures/SKIN/url") + .and_then(|v| v.as_str()) + { info.skin_url = Some(skin_url.to_owned()); } } @@ -1215,28 +1672,33 @@ impl Server { // This isn't an issue for other players because this packet // must come before the spawn player packet. if info.uuid == self.uuid { - let model = self.entities.get_component_mut_direct::(self.player.unwrap()).unwrap(); + let model = self + .entities + .get_component_mut_direct::( + self.player.unwrap(), + ) + .unwrap(); model.set_skin(info.skin_url.clone()); } - }, + } UpdateGamemode { uuid, gamemode } => { if let Some(info) = self.players.get_mut(&uuid) { info.gamemode = Gamemode::from_int(gamemode.0); } - }, + } UpdateLatency { uuid, ping } => { if let Some(info) = self.players.get_mut(&uuid) { info.ping = ping.0; } - }, + } UpdateDisplayName { uuid, display } => { if let Some(info) = self.players.get_mut(&uuid) { info.display_name = display; } - }, + } Remove { uuid } => { self.players.remove(&uuid); - }, + } } } } @@ -1264,93 +1726,151 @@ impl Server { } } - fn on_chunk_data_biomes3d(&mut self, chunk_data: packet::play::clientbound::ChunkData_Biomes3D) { - self.world.load_chunk115( - chunk_data.chunk_x, - chunk_data.chunk_z, - chunk_data.new, - chunk_data.bitmask.0 as u16, - chunk_data.data.data - ).unwrap(); + fn on_chunk_data_biomes3d( + &mut self, + chunk_data: packet::play::clientbound::ChunkData_Biomes3D, + ) { + self.world + .load_chunk115( + chunk_data.chunk_x, + chunk_data.chunk_z, + chunk_data.new, + chunk_data.bitmask.0 as u16, + chunk_data.data.data, + ) + .unwrap(); self.load_block_entities(chunk_data.block_entities.data); } - fn on_chunk_data(&mut self, chunk_data: packet::play::clientbound::ChunkData) { - self.world.load_chunk19( - chunk_data.chunk_x, - chunk_data.chunk_z, - chunk_data.new, - chunk_data.bitmask.0 as u16, - chunk_data.data.data - ).unwrap(); + self.world + .load_chunk19( + chunk_data.chunk_x, + chunk_data.chunk_z, + chunk_data.new, + chunk_data.bitmask.0 as u16, + chunk_data.data.data, + ) + .unwrap(); self.load_block_entities(chunk_data.block_entities.data); } - fn on_chunk_data_heightmap(&mut self, chunk_data: packet::play::clientbound::ChunkData_HeightMap) { - self.world.load_chunk19( - chunk_data.chunk_x, - chunk_data.chunk_z, - chunk_data.new, - chunk_data.bitmask.0 as u16, - chunk_data.data.data - ).unwrap(); + fn on_chunk_data_heightmap( + &mut self, + chunk_data: packet::play::clientbound::ChunkData_HeightMap, + ) { + self.world + .load_chunk19( + chunk_data.chunk_x, + chunk_data.chunk_z, + chunk_data.new, + chunk_data.bitmask.0 as u16, + chunk_data.data.data, + ) + .unwrap(); self.load_block_entities(chunk_data.block_entities.data); } - fn on_chunk_data_no_entities(&mut self, chunk_data: packet::play::clientbound::ChunkData_NoEntities) { - self.world.load_chunk19( - chunk_data.chunk_x, - chunk_data.chunk_z, - chunk_data.new, - chunk_data.bitmask.0 as u16, - chunk_data.data.data - ).unwrap(); + fn on_chunk_data_no_entities( + &mut self, + chunk_data: packet::play::clientbound::ChunkData_NoEntities, + ) { + self.world + .load_chunk19( + chunk_data.chunk_x, + chunk_data.chunk_z, + chunk_data.new, + chunk_data.bitmask.0 as u16, + chunk_data.data.data, + ) + .unwrap(); } - fn on_chunk_data_no_entities_u16(&mut self, chunk_data: packet::play::clientbound::ChunkData_NoEntities_u16) { + fn on_chunk_data_no_entities_u16( + &mut self, + chunk_data: packet::play::clientbound::ChunkData_NoEntities_u16, + ) { let chunk_meta = vec![crate::protocol::packet::ChunkMeta { x: chunk_data.chunk_x, z: chunk_data.chunk_z, bitmask: chunk_data.bitmask, }]; let skylight = false; - self.world.load_chunks18(chunk_data.new, skylight, &chunk_meta, chunk_data.data.data).unwrap(); + self.world + .load_chunks18(chunk_data.new, skylight, &chunk_meta, chunk_data.data.data) + .unwrap(); } fn on_chunk_data_17(&mut self, chunk_data: packet::play::clientbound::ChunkData_17) { - self.world.load_chunk17(chunk_data.chunk_x, chunk_data.chunk_z, chunk_data.new, chunk_data.bitmask, chunk_data.add_bitmask, chunk_data.compressed_data.data).unwrap(); + self.world + .load_chunk17( + chunk_data.chunk_x, + chunk_data.chunk_z, + chunk_data.new, + chunk_data.bitmask, + chunk_data.add_bitmask, + chunk_data.compressed_data.data, + ) + .unwrap(); } fn on_chunk_data_bulk(&mut self, bulk: packet::play::clientbound::ChunkDataBulk) { let new = true; - self.world.load_chunks18(new, bulk.skylight, &bulk.chunk_meta.data, bulk.chunk_data.to_vec()).unwrap(); + self.world + .load_chunks18( + new, + bulk.skylight, + &bulk.chunk_meta.data, + bulk.chunk_data.to_vec(), + ) + .unwrap(); } fn on_chunk_data_bulk_17(&mut self, bulk: packet::play::clientbound::ChunkDataBulk_17) { - self.world.load_chunks17(bulk.chunk_column_count, bulk.data_length, bulk.skylight, &bulk.chunk_data_and_meta).unwrap(); + self.world + .load_chunks17( + bulk.chunk_column_count, + bulk.data_length, + bulk.skylight, + &bulk.chunk_data_and_meta, + ) + .unwrap(); } fn on_chunk_unload(&mut self, chunk_unload: packet::play::clientbound::ChunkUnload) { - self.world.unload_chunk(chunk_unload.x, chunk_unload.z, &mut self.entities); + self.world + .unload_chunk(chunk_unload.x, chunk_unload.z, &mut self.entities); } fn on_block_change(&mut self, location: Position, id: i32) { - self.world.set_block(location, block::Block::by_vanilla_id(id as usize, self.protocol_version, &self.world.modded_block_ids)) + self.world.set_block( + location, + block::Block::by_vanilla_id( + id as usize, + self.protocol_version, + &self.world.modded_block_ids, + ), + ) } - fn on_block_change_varint(&mut self, block_change: packet::play::clientbound::BlockChange_VarInt) { + fn on_block_change_varint( + &mut self, + block_change: packet::play::clientbound::BlockChange_VarInt, + ) { self.on_block_change(block_change.location, block_change.block_id.0) } fn on_block_change_u8(&mut self, block_change: packet::play::clientbound::BlockChange_u8) { self.on_block_change( crate::shared::Position::new(block_change.x, block_change.y as i32, block_change.z), - (block_change.block_id.0 << 4) | (block_change.block_metadata as i32) + (block_change.block_id.0 << 4) | (block_change.block_metadata as i32), ); } - fn on_multi_block_change_varint(&mut self, block_change: packet::play::clientbound::MultiBlockChange_VarInt) { + fn on_multi_block_change_varint( + &mut self, + block_change: packet::play::clientbound::MultiBlockChange_VarInt, + ) { let ox = block_change.chunk_x << 4; let oz = block_change.chunk_z << 4; for record in block_change.records.data { @@ -1358,20 +1878,27 @@ impl Server { Position::new( ox + (record.xz >> 4) as i32, record.y as i32, - oz + (record.xz & 0xF) as i32 + oz + (record.xz & 0xF) as i32, + ), + block::Block::by_vanilla_id( + record.block_id.0 as usize, + self.protocol_version, + &self.world.modded_block_ids, ), - block::Block::by_vanilla_id(record.block_id.0 as usize, self.protocol_version, &self.world.modded_block_ids) ); } } - fn on_multi_block_change_u16(&mut self, block_change: packet::play::clientbound::MultiBlockChange_u16) { + fn on_multi_block_change_u16( + &mut self, + block_change: packet::play::clientbound::MultiBlockChange_u16, + ) { let ox = block_change.chunk_x << 4; let oz = block_change.chunk_z << 4; let mut data = std::io::Cursor::new(block_change.data); - for _ in 0 .. block_change.record_count { + for _ in 0..block_change.record_count { use byteorder::{BigEndian, ReadBytesExt}; let record = data.read_u32::().unwrap(); @@ -1383,11 +1910,14 @@ impl Server { self.world.set_block( Position::new(x, y, z), - block::Block::by_vanilla_id(id as usize, self.protocol_version, &self.world.modded_block_ids) + block::Block::by_vanilla_id( + id as usize, + self.protocol_version, + &self.world.modded_block_ids, + ), ); } } - } #[derive(Debug, Clone, Copy)] diff --git a/src/server/plugin_messages.rs b/src/server/plugin_messages.rs index 42f75f6..0ba269e 100644 --- a/src/server/plugin_messages.rs +++ b/src/server/plugin_messages.rs @@ -1,4 +1,3 @@ - use crate::protocol::packet::play::serverbound::PluginMessageServerbound; use crate::protocol::packet::play::serverbound::PluginMessageServerbound_i16; use crate::protocol::{Serializable, VarShort}; @@ -34,5 +33,4 @@ impl Brand { data: crate::protocol::LenPrefixedBytes::::new(data), } } - } diff --git a/src/server/sun.rs b/src/server/sun.rs index 5596116..9855c88 100644 --- a/src/server/sun.rs +++ b/src/server/sun.rs @@ -1,7 +1,6 @@ - use crate::render; use crate::render::model; -use cgmath::{Vector3, Matrix4, Decomposed, Rotation3, Rad, Quaternion}; +use cgmath::{Decomposed, Matrix4, Quaternion, Rad, Rotation3, Vector3}; pub struct SunModel { sun: model::ModelKey, @@ -12,7 +11,6 @@ pub struct SunModel { const SIZE: f32 = 50.0; impl SunModel { - pub fn new(renderer: &mut render::Renderer) -> SunModel { SunModel { sun: SunModel::generate_sun(renderer), @@ -71,26 +69,123 @@ impl SunModel { renderer.model.create_model( model::SUN, vec![vec![ - model::Vertex{x: 0.0, y: -SIZE, z: -SIZE, texture_x: 0.0, texture_y: 1.0, texture: tex.clone(), r: 255, g: 255, b: 255, a: 0, id: 0}, - model::Vertex{x: 0.0, y: SIZE, z: -SIZE, texture_x: 0.0, texture_y: 0.0, texture: tex.clone(), r: 255, g: 255, b: 255, a: 0, id: 0}, - model::Vertex{x: 0.0, y: -SIZE, z: SIZE, texture_x: 1.0, texture_y: 1.0, texture: tex.clone(), r: 255, g: 255, b: 255, a: 0, id: 0}, - model::Vertex{x: 0.0, y: SIZE, z: SIZE, texture_x: 1.0, texture_y: 0.0, texture: tex.clone(), r: 255, g: 255, b: 255, a: 0, id: 0} - ]] + model::Vertex { + x: 0.0, + y: -SIZE, + z: -SIZE, + texture_x: 0.0, + texture_y: 1.0, + texture: tex.clone(), + r: 255, + g: 255, + b: 255, + a: 0, + id: 0, + }, + model::Vertex { + x: 0.0, + y: SIZE, + z: -SIZE, + texture_x: 0.0, + texture_y: 0.0, + texture: tex.clone(), + r: 255, + g: 255, + b: 255, + a: 0, + id: 0, + }, + model::Vertex { + x: 0.0, + y: -SIZE, + z: SIZE, + texture_x: 1.0, + texture_y: 1.0, + texture: tex.clone(), + r: 255, + g: 255, + b: 255, + a: 0, + id: 0, + }, + model::Vertex { + x: 0.0, + y: SIZE, + z: SIZE, + texture_x: 1.0, + texture_y: 0.0, + texture: tex.clone(), + r: 255, + g: 255, + b: 255, + a: 0, + id: 0, + }, + ]], ) } pub fn generate_moon(renderer: &mut render::Renderer, phase: i32) -> model::ModelKey { - let tex = render::Renderer::get_texture(renderer.get_textures_ref(), "environment/moon_phases"); + let tex = + render::Renderer::get_texture(renderer.get_textures_ref(), "environment/moon_phases"); let mpx = (phase % 4) as f64 * (1.0 / 4.0); let mpy = (phase / 4) as f64 * (1.0 / 2.0); renderer.model.create_model( model::SUN, vec![vec![ - model::Vertex{x: 0.0, y: -SIZE, z: -SIZE, texture_x: mpx, texture_y: mpy + (1.0 / 2.0), texture: tex.clone(), r: 255, g: 255, b: 255, a: 0, id: 0}, - model::Vertex{x: 0.0, y: SIZE, z: -SIZE, texture_x: mpx, texture_y: mpy, texture: tex.clone(), r: 255, g: 255, b: 255, a: 0, id: 0}, - model::Vertex{x: 0.0, y: -SIZE, z: SIZE, texture_x: mpx + (1.0 / 4.0), texture_y: mpy + (1.0 / 2.0), texture: tex.clone(), r: 255, g: 255, b: 255, a: 0, id: 0}, - model::Vertex{x: 0.0, y: SIZE, z: SIZE, texture_x: mpx + (1.0 / 4.0), texture_y: mpy, texture: tex.clone(), r: 255, g: 255, b: 255, a: 0, id: 0} - ]] + model::Vertex { + x: 0.0, + y: -SIZE, + z: -SIZE, + texture_x: mpx, + texture_y: mpy + (1.0 / 2.0), + texture: tex.clone(), + r: 255, + g: 255, + b: 255, + a: 0, + id: 0, + }, + model::Vertex { + x: 0.0, + y: SIZE, + z: -SIZE, + texture_x: mpx, + texture_y: mpy, + texture: tex.clone(), + r: 255, + g: 255, + b: 255, + a: 0, + id: 0, + }, + model::Vertex { + x: 0.0, + y: -SIZE, + z: SIZE, + texture_x: mpx + (1.0 / 4.0), + texture_y: mpy + (1.0 / 2.0), + texture: tex.clone(), + r: 255, + g: 255, + b: 255, + a: 0, + id: 0, + }, + model::Vertex { + x: 0.0, + y: SIZE, + z: SIZE, + texture_x: mpx + (1.0 / 4.0), + texture_y: mpy, + texture: tex.clone(), + r: 255, + g: 255, + b: 255, + a: 0, + id: 0, + }, + ]], ) } } diff --git a/src/server/target.rs b/src/server/target.rs index 63c8e1a..ebb103b 100644 --- a/src/server/target.rs +++ b/src/server/target.rs @@ -1,10 +1,9 @@ - -use crate::world; -use crate::world::block; -use crate::shared::{Position, Direction}; -use cgmath; use crate::render; use crate::render::model; +use crate::shared::{Direction, Position}; +use crate::world; +use crate::world::block; +use cgmath; use collision::{self, Aabb}; pub struct Info { @@ -17,13 +16,13 @@ impl Info { pub fn new() -> Info { Info { model: None, - last_block: block::Air{}, + last_block: block::Air {}, last_pos: Position::new(0, 0, 0), } } pub fn clear(&mut self, renderer: &mut render::Renderer) { - self.last_block = block::Air{}; + self.last_block = block::Air {}; if let Some(model) = self.model.take() { renderer.model.remove_model(model); } @@ -44,16 +43,27 @@ impl Info { let tex = render::Renderer::get_texture(renderer.get_textures_ref(), "steven:solid"); for bound in bl.get_collision_boxes() { - let bound = bound.add_v(cgmath::Vector3::new(pos.x as f64, pos.y as f64, pos.z as f64)); + let bound = bound.add_v(cgmath::Vector3::new( + pos.x as f64, + pos.y as f64, + pos.z as f64, + )); for point in [ (bound.min.x, bound.min.z), (bound.min.x, bound.max.z), (bound.max.x, bound.min.z), (bound.max.x, bound.max.z), - ].iter() { - model::append_box(&mut parts, - (point.0-LINE_SIZE) as f32, (bound.min.y-LINE_SIZE) as f32, (point.1-LINE_SIZE) as f32, - (LINE_SIZE*2.0) as f32, ((bound.max.y-bound.min.y)+LINE_SIZE*2.0) as f32, (LINE_SIZE*2.0) as f32, + ] + .iter() + { + model::append_box( + &mut parts, + (point.0 - LINE_SIZE) as f32, + (bound.min.y - LINE_SIZE) as f32, + (point.1 - LINE_SIZE) as f32, + (LINE_SIZE * 2.0) as f32, + ((bound.max.y - bound.min.y) + LINE_SIZE * 2.0) as f32, + (LINE_SIZE * 2.0) as f32, [ Some(tex.clone()), Some(tex.clone()), @@ -61,7 +71,8 @@ impl Info { Some(tex.clone()), Some(tex.clone()), Some(tex.clone()), - ]); + ], + ); } for point in [ @@ -69,10 +80,17 @@ impl Info { (bound.min.x, bound.max.z, bound.max.x, bound.max.z), (bound.min.x, bound.min.z, bound.min.x, bound.max.z), (bound.max.x, bound.min.z, bound.max.x, bound.max.z), - ].iter() { - model::append_box(&mut parts, - (point.0-LINE_SIZE) as f32, (bound.min.y-LINE_SIZE) as f32, (point.1-LINE_SIZE) as f32, - ((point.2-point.0)+(LINE_SIZE*2.0)) as f32, (LINE_SIZE*2.0) as f32, ((point.3-point.1)+(LINE_SIZE*2.0)) as f32, + ] + .iter() + { + model::append_box( + &mut parts, + (point.0 - LINE_SIZE) as f32, + (bound.min.y - LINE_SIZE) as f32, + (point.1 - LINE_SIZE) as f32, + ((point.2 - point.0) + (LINE_SIZE * 2.0)) as f32, + (LINE_SIZE * 2.0) as f32, + ((point.3 - point.1) + (LINE_SIZE * 2.0)) as f32, [ Some(tex.clone()), Some(tex.clone()), @@ -80,10 +98,16 @@ impl Info { Some(tex.clone()), Some(tex.clone()), Some(tex.clone()), - ]); - model::append_box(&mut parts, - (point.0-LINE_SIZE) as f32, (bound.max.y-LINE_SIZE) as f32, (point.1-LINE_SIZE) as f32, - ((point.2-point.0)+(LINE_SIZE*2.0)) as f32, (LINE_SIZE*2.0) as f32, ((point.3-point.1)+(LINE_SIZE*2.0)) as f32, + ], + ); + model::append_box( + &mut parts, + (point.0 - LINE_SIZE) as f32, + (bound.max.y - LINE_SIZE) as f32, + (point.1 - LINE_SIZE) as f32, + ((point.2 - point.0) + (LINE_SIZE * 2.0)) as f32, + (LINE_SIZE * 2.0) as f32, + ((point.3 - point.1) + (LINE_SIZE * 2.0)) as f32, [ Some(tex.clone()), Some(tex.clone()), @@ -91,7 +115,8 @@ impl Info { Some(tex.clone()), Some(tex.clone()), Some(tex.clone()), - ]); + ], + ); } } @@ -105,7 +130,15 @@ impl Info { } } -pub fn test_block(world: &world::World, pos: Position, s: cgmath::Vector3, d: cgmath::Vector3) -> (bool, Option<(Position, block::Block, Direction, cgmath::Vector3)>) { +pub fn test_block( + world: &world::World, + pos: Position, + s: cgmath::Vector3, + d: cgmath::Vector3, +) -> ( + bool, + Option<(Position, block::Block, Direction, cgmath::Vector3)>, +) { let block = world.get_block(pos); let posf = cgmath::Vector3::new(pos.x as f64, pos.y as f64, pos.z as f64); for bound in block.get_collision_boxes() { @@ -137,7 +170,11 @@ fn find_face(bound: collision::Aabb3, hit: cgmath::Vector3) -> Directi } } -fn intersects_line(bound: collision::Aabb3, origin: cgmath::Vector3, dir: cgmath::Vector3) -> Option> { +fn intersects_line( + bound: collision::Aabb3, + origin: cgmath::Vector3, + dir: cgmath::Vector3, +) -> Option> { const RIGHT: usize = 0; const LEFT: usize = 1; const MIDDLE: usize = 2; @@ -145,7 +182,7 @@ fn intersects_line(bound: collision::Aabb3, origin: cgmath::Vector3, d let mut candidate_plane = [0.0, 0.0, 0.0]; let mut max_t = [0.0, 0.0, 0.0]; let mut inside = true; - for i in 0 .. 3 { + for i in 0..3 { if origin[i] < bound.min[i] { quadrant[i] = LEFT; candidate_plane[i] = bound.min[i]; @@ -162,13 +199,13 @@ fn intersects_line(bound: collision::Aabb3, origin: cgmath::Vector3, d return Some(origin); } - for i in 0 .. 3 { + for i in 0..3 { if quadrant[i] != MIDDLE && dir[i] != 0.0 { max_t[i] = (candidate_plane[i] - origin[i]) / dir[i]; } } let mut which_plane = 0; - for i in 1 .. 3 { + for i in 1..3 { if max_t[which_plane] < max_t[i] { which_plane = i; } @@ -178,7 +215,7 @@ fn intersects_line(bound: collision::Aabb3, origin: cgmath::Vector3, d } let mut coord = cgmath::Vector3::new(0.0, 0.0, 0.0); - for i in 0 .. 3 { + for i in 0..3 { if which_plane != i { coord[i] = origin[i] + max_t[which_plane] * dir[i]; if coord[i] < bound.min[i] || coord[i] > bound.max[i] { @@ -191,8 +228,16 @@ fn intersects_line(bound: collision::Aabb3, origin: cgmath::Vector3, d Some(coord) } -pub fn trace_ray(world: &world::World, max: f64, s: cgmath::Vector3, d: cgmath::Vector3, collide_func: F) -> Option - where F: Fn(&world::World, Position, cgmath::Vector3, cgmath::Vector3,) -> (bool, Option) { +pub fn trace_ray( + world: &world::World, + max: f64, + s: cgmath::Vector3, + d: cgmath::Vector3, + collide_func: F, +) -> Option +where + F: Fn(&world::World, Position, cgmath::Vector3, cgmath::Vector3) -> (bool, Option), +{ struct Gen { count: i32, base: f64, @@ -208,11 +253,7 @@ pub fn trace_ray(world: &world::World, max: f64, s: cgmath::Vector3, } else { 0.0 }; - Gen { - count: 0, - base, - d, - } + Gen { count: 0, base, d } } fn next(&mut self) -> f64 { diff --git a/src/settings.rs b/src/settings.rs index 20bee79..fc26058 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,6 +1,6 @@ use crate::console; -use std::marker::PhantomData; use glutin::event::VirtualKeyCode; +use std::marker::PhantomData; // Might just rename this to settings.rs pub const R_MAX_FPS: console::CVar = console::CVar { @@ -40,24 +40,37 @@ pub const CL_MASTER_VOLUME: console::CVar = console::CVar { }; macro_rules! create_keybind { - ($keycode:ident, $name:expr, $description:expr) => (console::CVar { - ty: PhantomData, - name: $name, - description: $description, - mutable: true, - serializable: true, - default: &|| VirtualKeyCode::$keycode as i64 - }) + ($keycode:ident, $name:expr, $description:expr) => { + console::CVar { + ty: PhantomData, + name: $name, + description: $description, + mutable: true, + serializable: true, + default: &|| VirtualKeyCode::$keycode as i64, + } + }; } -pub const CL_KEYBIND_FORWARD: console::CVar = create_keybind!(W, "cl_keybind_forward", "Keybinding for moving forward"); -pub const CL_KEYBIND_BACKWARD: console::CVar = create_keybind!(S, "cl_keybind_backward", "Keybinding for moving backward"); -pub const CL_KEYBIND_LEFT: console::CVar = create_keybind!(A, "cl_keybind_left", "Keybinding for moving the left"); -pub const CL_KEYBIND_RIGHT: console::CVar = create_keybind!(D, "cl_keybind_right", "Keybinding for moving to the right"); -pub const CL_KEYBIND_OPEN_INV: console::CVar = create_keybind!(E, "cl_keybind_open_inv", "Keybinding for opening the inventory"); -pub const CL_KEYBIND_SNEAK: console::CVar = create_keybind!(LShift, "cl_keybind_sneak", "Keybinding for sneaking"); -pub const CL_KEYBIND_SPRINT: console::CVar = create_keybind!(LControl, "cl_keybind_sprint", "Keybinding for sprinting"); -pub const CL_KEYBIND_JUMP: console::CVar = create_keybind!(Space, "cl_keybind_jump", "Keybinding for jumping"); +pub const CL_KEYBIND_FORWARD: console::CVar = + create_keybind!(W, "cl_keybind_forward", "Keybinding for moving forward"); +pub const CL_KEYBIND_BACKWARD: console::CVar = + create_keybind!(S, "cl_keybind_backward", "Keybinding for moving backward"); +pub const CL_KEYBIND_LEFT: console::CVar = + create_keybind!(A, "cl_keybind_left", "Keybinding for moving the left"); +pub const CL_KEYBIND_RIGHT: console::CVar = + create_keybind!(D, "cl_keybind_right", "Keybinding for moving to the right"); +pub const CL_KEYBIND_OPEN_INV: console::CVar = create_keybind!( + E, + "cl_keybind_open_inv", + "Keybinding for opening the inventory" +); +pub const CL_KEYBIND_SNEAK: console::CVar = + create_keybind!(LShift, "cl_keybind_sneak", "Keybinding for sneaking"); +pub const CL_KEYBIND_SPRINT: console::CVar = + create_keybind!(LControl, "cl_keybind_sprint", "Keybinding for sprinting"); +pub const CL_KEYBIND_JUMP: console::CVar = + create_keybind!(Space, "cl_keybind_jump", "Keybinding for jumping"); pub const DOUBLE_JUMP_MS: u32 = 100; @@ -90,15 +103,22 @@ pub enum Stevenkey { impl Stevenkey { pub fn values() -> Vec { - vec!(Stevenkey::Forward, Stevenkey::Backward, Stevenkey::Left, - Stevenkey::Right, Stevenkey::OpenInv, Stevenkey::Sneak, - Stevenkey::Sprint, Stevenkey::Jump) + vec![ + Stevenkey::Forward, + Stevenkey::Backward, + Stevenkey::Left, + Stevenkey::Right, + Stevenkey::OpenInv, + Stevenkey::Sneak, + Stevenkey::Sprint, + Stevenkey::Jump, + ] } pub fn get_by_keycode(keycode: VirtualKeyCode, vars: &console::Vars) -> Option { for steven_key in Stevenkey::values() { if keycode as i64 == *vars.get(steven_key.get_cvar()) { - return Some(steven_key) + return Some(steven_key); } } None @@ -113,7 +133,7 @@ impl Stevenkey { Stevenkey::OpenInv => CL_KEYBIND_OPEN_INV, Stevenkey::Sneak => CL_KEYBIND_SNEAK, Stevenkey::Sprint => CL_KEYBIND_SPRINT, - Stevenkey::Jump => CL_KEYBIND_JUMP + Stevenkey::Jump => CL_KEYBIND_JUMP, } } } diff --git a/src/ui/logo.rs b/src/ui/logo.rs index 976faae..20f9c84 100644 --- a/src/ui/logo.rs +++ b/src/ui/logo.rs @@ -1,12 +1,11 @@ - -use std::sync::{Arc, RwLock}; -use std::f64::consts; -use crate::ui; use crate::render; use crate::resources; -use std::time::{SystemTime, UNIX_EPOCH}; +use crate::ui; use rand::{self, seq::SliceRandom}; use rand_pcg; +use std::f64::consts; +use std::sync::{Arc, RwLock}; +use std::time::{SystemTime, UNIX_EPOCH}; pub struct Logo { _shadow: ui::BatchRef, @@ -20,9 +19,10 @@ pub struct Logo { } impl Logo { - pub fn new(resources: Arc>, - ui_container: &mut ui::Container) - -> Logo { + pub fn new( + resources: Arc>, + ui_container: &mut ui::Container, + ) -> Logo { let logo_str = { let res = resources.read().unwrap(); let mut logo = res.open("steven", "logo/logo.txt").unwrap(); @@ -66,14 +66,15 @@ impl Logo { .colour((0, 0, 0, 100)) .attach(&mut *shadow_batch.borrow_mut()); - ui::ImageBuilder::new() .texture("minecraft:blocks/planks_oak") .position(x as f64, y as f64) .size(4.0, 8.0) .texture_coords(( - (x % 16) as f64 / 16.0, (y % 16) as f64 / 16.0, - 4.0 / 16.0, 8.0 / 16.0 + (x % 16) as f64 / 16.0, + (y % 16) as f64 / 16.0, + 4.0 / 16.0, + 8.0 / 16.0, )) .colour((r, g, b, 255)) .attach(&mut *layer0.borrow_mut()); @@ -101,7 +102,8 @@ impl Logo { text_strings.push(line.to_owned().replace("\r", "")); } } - let mut r: rand_pcg::Pcg32 = rand::SeedableRng::from_seed([45, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 12, 0, 0, 0]); + let mut r: rand_pcg::Pcg32 = + rand::SeedableRng::from_seed([45, 0, 0, 0, 64, 0, 0, 0, 32, 0, 0, 0, 12, 0, 0, 0]); text_strings.shuffle(&mut r); } @@ -147,7 +149,7 @@ impl Logo { if self.text_base_scale > 1.0 { self.text_base_scale = 1.0; } - text.x =(-width / 2.0) * self.text_base_scale; + text.x = (-width / 2.0) * self.text_base_scale; self.text_orig_x = text.x; } @@ -160,6 +162,6 @@ impl Logo { text.scale_x = (0.7 + (offset / 3.0)) * self.text_base_scale; text.scale_y = (0.7 + (offset / 3.0)) * self.text_base_scale; let scale = text.scale_x; - text.x =self.text_orig_x * scale * self.text_base_scale; + text.x = self.text_orig_x * scale * self.text_base_scale; } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 2e81c70..86dedb3 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -14,18 +14,17 @@ pub mod logo; -use std::rc::{Rc, Weak}; -use std::cell::{RefCell, RefMut}; -use crate::render; use crate::format; -use glutin::event::VirtualKeyCode; +use crate::render; #[cfg(not(target_arch = "wasm32"))] -use clipboard::{ClipboardProvider, ClipboardContext}; +use clipboard::{ClipboardContext, ClipboardProvider}; +use glutin::event::VirtualKeyCode; +use std::cell::{RefCell, RefMut}; +use std::rc::{Rc, Weak}; const SCALED_WIDTH: f64 = 854.0; const SCALED_HEIGHT: f64 = 480.0; - #[derive(Clone, Copy, PartialEq)] pub enum Mode { Scaled, @@ -56,8 +55,10 @@ struct Region { impl Region { fn intersects(&self, o: &Region) -> bool { - !(self.x + self.w < o.x || self.x > o.x + o.w || self.y + self.h < o.y || - self.y > o.y + o.h) + !(self.x + self.w < o.x + || self.x > o.x + o.w + || self.y + self.h < o.y + || self.y > o.y + o.h) } } @@ -304,8 +305,13 @@ impl Container { Mode::Unscaled(scale) => (scale, scale), }; - if self.last_sw != sw || self.last_sh != sh || self.last_width != width || - self.last_height != height || self.version != renderer.ui.version || self.last_mode != self.mode { + if self.last_sw != sw + || self.last_sh != sh + || self.last_width != width + || self.last_height != height + || self.version != renderer.ui.version + || self.last_mode != self.mode + { self.last_sw = sw; self.last_sh = sh; self.last_width = width; @@ -324,9 +330,12 @@ impl Container { // If we don't have an element focused, focus one if !self.focusable_elements.is_empty() - && !self.focusable_elements.iter() - .flat_map(|v| v.upgrade()) - .any(|v| v.is_focused()) { + && !self + .focusable_elements + .iter() + .flat_map(|v| v.upgrade()) + .any(|v| v.is_focused()) + { self.cycle_focus() } @@ -380,13 +389,14 @@ impl Container { if self.focusable_elements.is_empty() { return; } - let focusables = self.focusable_elements.iter() + let focusables = self + .focusable_elements + .iter() .flat_map(|v| v.upgrade()) .collect::>(); // Find the last focused element if there is one - let last_focus = focusables.iter() - .position(|v| v.is_focused()); + let last_focus = focusables.iter().position(|v| v.is_focused()); let next_focus = last_focus.map_or(0, |v| v + 1) % focusables.len(); // Clear the last focus @@ -397,15 +407,20 @@ impl Container { focusables[next_focus].set_focused(true); } - pub fn key_press(&mut self, game: &mut crate::Game, key: VirtualKeyCode, down: bool, ctrl_pressed: bool) { + pub fn key_press( + &mut self, + game: &mut crate::Game, + key: VirtualKeyCode, + down: bool, + ctrl_pressed: bool, + ) { if key == VirtualKeyCode::Tab { if !down { self.cycle_focus(); } return; } - for el in self.focusable_elements.iter() - .flat_map(|v| v.upgrade()) { + for el in self.focusable_elements.iter().flat_map(|v| v.upgrade()) { if el.is_focused() { el.key_press(game, key, down, ctrl_pressed); } @@ -416,8 +431,7 @@ impl Container { if c < ' ' { return; } - for el in self.focusable_elements.iter() - .flat_map(|v| v.upgrade()) { + for el in self.focusable_elements.iter().flat_map(|v| v.upgrade()) { if el.is_focused() { el.key_type(game, c); } @@ -463,11 +477,27 @@ impl ElementHolder for Container { } trait UIElement { - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, sw: f64, sh: f64, width: f64, height: f64, delta: f64) -> &mut [u8]; + fn draw( + &mut self, + renderer: &mut render::Renderer, + r: &Region, + sw: f64, + sh: f64, + width: f64, + height: f64, + delta: f64, + ) -> &mut [u8]; fn get_size(&self) -> (f64, f64); fn is_dirty(&self) -> bool; fn post_init(_: Rc>) {} - fn key_press(&mut self, _game: &mut crate::Game, _key: VirtualKeyCode, _down: bool, _ctrl_pressed: bool) {} + fn key_press( + &mut self, + _game: &mut crate::Game, + _key: VirtualKeyCode, + _down: bool, + _ctrl_pressed: bool, + ) { + } fn key_type(&mut self, _game: &mut crate::Game, _c: char) {} fn tick(&mut self, renderer: &mut render::Renderer); } @@ -804,14 +834,29 @@ impl ImageBuilder { } impl UIElement for Image { - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, sw: f64, sh: f64, width: f64, height: f64, delta: f64) -> &mut [u8] { + fn draw( + &mut self, + renderer: &mut render::Renderer, + r: &Region, + sw: f64, + sh: f64, + width: f64, + height: f64, + delta: f64, + ) -> &mut [u8] { if self.check_rebuild() { self.data.clear(); let texture = render::Renderer::get_texture(renderer.get_textures_ref(), &self.texture); let mut element = render::ui::UIElement::new( &texture, - r.x, r.y, r.w, r.h, - self.texture_coords.0, self.texture_coords.1, self.texture_coords.2, self.texture_coords.3, + r.x, + r.y, + r.w, + r.h, + self.texture_coords.0, + self.texture_coords.1, + self.texture_coords.2, + self.texture_coords.3, ); element.r = self.colour.0; element.g = self.colour.1; @@ -862,7 +907,16 @@ impl BatchBuilder { } impl UIElement for Batch { - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, sw: f64, sh: f64, width: f64, height: f64, delta: f64) -> &mut [u8] { + fn draw( + &mut self, + renderer: &mut render::Renderer, + r: &Region, + sw: f64, + sh: f64, + width: f64, + height: f64, + delta: f64, + ) -> &mut [u8] { if self.check_rebuild() { self.data.clear(); self.super_draw(renderer, r, sw, sh, width, height, delta); @@ -916,15 +970,29 @@ element! { } impl UIElement for Text { - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, sw: f64, sh: f64, width: f64, height: f64, delta: f64) -> &mut [u8] { + fn draw( + &mut self, + renderer: &mut render::Renderer, + r: &Region, + sw: f64, + sh: f64, + width: f64, + height: f64, + delta: f64, + ) -> &mut [u8] { if self.check_rebuild() { self.data.clear(); let mut text = if self.rotation == 0.0 { renderer.ui.new_text_scaled( &self.text, - r.x, r.y, sw * self.scale_x, sh * self.scale_y, - self.colour.0, self.colour.1, self.colour.2, + r.x, + r.y, + sw * self.scale_x, + sh * self.scale_y, + self.colour.0, + self.colour.1, + self.colour.2, ) } else { let c = self.rotation.cos(); @@ -934,11 +1002,15 @@ impl UIElement for Text { let w = (tmpx * c - tmpy * s).abs(); let h = (tmpy * c + tmpx * s).abs(); renderer.ui.new_text_rotated( - &self.text, - r.x + w - (r.w / 2.0), r.y + h - (r.h / 2.0), - sw * self.scale_x, sh * self.scale_y, - self.rotation, - self.colour.0, self.colour.1, self.colour.2, + &self.text, + r.x + w - (r.w / 2.0), + r.y + h - (r.h / 2.0), + sw * self.scale_x, + sh * self.scale_y, + self.rotation, + self.colour.0, + self.colour.1, + self.colour.2, ) }; for e in &mut text.elements { @@ -964,7 +1036,10 @@ impl UIElement for Text { } fn get_size(&self) -> (f64, f64) { - ((self.width + 2.0) * self.scale_x, self.height * self.scale_y) + ( + (self.width + 2.0) * self.scale_x, + self.height * self.scale_y, + ) } fn is_dirty(&self) -> bool { @@ -976,8 +1051,6 @@ impl UIElement for Text { } } - - element! { ref FormattedRef pub struct Formatted { @@ -1011,7 +1084,16 @@ element! { } impl UIElement for Formatted { - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, sw: f64, sh: f64, width: f64, height: f64, delta: f64) -> &mut [u8] { + fn draw( + &mut self, + renderer: &mut render::Renderer, + r: &Region, + sw: f64, + sh: f64, + width: f64, + height: f64, + delta: f64, + ) -> &mut [u8] { if self.check_rebuild() { self.data.clear(); @@ -1058,7 +1140,10 @@ impl UIElement for Formatted { } fn get_size(&self) -> (f64, f64) { - ((self.width + 2.0) * self.scale_x, self.height * self.scale_y) + ( + (self.width + 2.0) * self.scale_x, + self.height * self.scale_y, + ) } fn is_dirty(&self) -> bool { @@ -1075,7 +1160,11 @@ impl Formatted { self.dirty = true; } - pub fn compute_size(renderer: &render::Renderer, text: &format::Component, max_width: f64) -> (f64, f64) { + pub fn compute_size( + renderer: &render::Renderer, + text: &format::Component, + max_width: f64, + ) -> (f64, f64) { let mut state = FormatState { lines: 0, width: 0.0, @@ -1098,14 +1187,13 @@ struct FormatState<'a> { renderer: &'a render::Renderer, } - -impl <'a> ElementHolder for FormatState<'a> { +impl<'a> ElementHolder for FormatState<'a> { fn add(&mut self, el: Element, _: bool) { self.text.push(el); } } -impl <'a> FormatState<'a> { +impl<'a> FormatState<'a> { fn build(&mut self, c: &format::Component, color: format::Color) { match *c { format::Component::Text(ref txt) => { @@ -1197,46 +1285,156 @@ impl ButtonBuilder { } impl UIElement for Button { - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, sw: f64, sh: f64, width: f64, height: f64, delta: f64) -> &mut [u8] { + fn draw( + &mut self, + renderer: &mut render::Renderer, + r: &Region, + sw: f64, + sh: f64, + width: f64, + height: f64, + delta: f64, + ) -> &mut [u8] { if self.check_rebuild() { self.data.clear(); let offset = match (self.disabled, self.hovered) { - (true, _) => 46.0, - (false, true) => 86.0, - (false, false) => 66.0, + (true, _) => 46.0, + (false, true) => 86.0, + (false, false) => 66.0, }; let texture = render::Renderer::get_texture(renderer.get_textures_ref(), "gui/widgets") - .relative(0.0, offset / 256.0, 200.0 / 256.0, 20.0 / 256.0); + .relative(0.0, offset / 256.0, 200.0 / 256.0, 20.0 / 256.0); - self.data.extend(render::ui::UIElement::new(&texture, r.x, r.y, 4.0 * sw, 4.0 * sh, 0.0, 0.0, 2.0/200.0, 2.0/20.0).bytes(width, height)); - self.data.extend(render::ui::UIElement::new(&texture, r.x + r.w - 4.0 * sw, r.y, 4.0 * sw, 4.0 * sh, 198.0/200.0, 0.0, 2.0/200.0, 2.0/20.0).bytes(width, height)); - self.data.extend(render::ui::UIElement::new(&texture, r.x, r.y + r.h - 6.0 * sh, 4.0 * sw, 6.0 * sh, 0.0, 17.0/20.0, 2.0/200.0, 3.0/20.0).bytes(width, height)); - self.data.extend(render::ui::UIElement::new(&texture, r.x + r.w - 4.0 * sw, r.y + r.h - 6.0 * sh, 4.0 * sw, 6.0 * sh, 198.0/200.0, 17.0/20.0, 2.0/200.0, 3.0/20.0).bytes(width, height)); - - let w = ((r.w / sw)/2.0) - 4.0; - self.data.extend(render::ui::UIElement::new( - &texture.relative(2.0/200.0, 0.0, 196.0/200.0, 2.0/20.0), - r.x+4.0*sw, r.y, r.w - 8.0 * sw, 4.0 * sh, 0.0, 0.0, w/196.0, 1.0).bytes(width, height) + self.data.extend( + render::ui::UIElement::new( + &texture, + r.x, + r.y, + 4.0 * sw, + 4.0 * sh, + 0.0, + 0.0, + 2.0 / 200.0, + 2.0 / 20.0, + ) + .bytes(width, height), ); - self.data.extend(render::ui::UIElement::new( - &texture.relative(2.0/200.0, 17.0/20.0, 196.0/200.0, 3.0/20.0), - r.x+4.0*sw, r.y+r.h-6.0*sh, r.w - 8.0 * sw, 6.0 * sh, 0.0, 0.0, w/196.0, 1.0).bytes(width, height) + self.data.extend( + render::ui::UIElement::new( + &texture, + r.x + r.w - 4.0 * sw, + r.y, + 4.0 * sw, + 4.0 * sh, + 198.0 / 200.0, + 0.0, + 2.0 / 200.0, + 2.0 / 20.0, + ) + .bytes(width, height), + ); + self.data.extend( + render::ui::UIElement::new( + &texture, + r.x, + r.y + r.h - 6.0 * sh, + 4.0 * sw, + 6.0 * sh, + 0.0, + 17.0 / 20.0, + 2.0 / 200.0, + 3.0 / 20.0, + ) + .bytes(width, height), + ); + self.data.extend( + render::ui::UIElement::new( + &texture, + r.x + r.w - 4.0 * sw, + r.y + r.h - 6.0 * sh, + 4.0 * sw, + 6.0 * sh, + 198.0 / 200.0, + 17.0 / 20.0, + 2.0 / 200.0, + 3.0 / 20.0, + ) + .bytes(width, height), ); - let h = ((r.h / sh)/2.0) - 5.0; - self.data.extend(render::ui::UIElement::new( - &texture.relative(0.0/200.0, 2.0/20.0, 2.0/200.0, 15.0/20.0), - r.x, r.y + 4.0*sh, 4.0 * sw, r.h - 10.0*sh, 0.0, 0.0, 1.0, h/16.0).bytes(width, height) + let w = ((r.w / sw) / 2.0) - 4.0; + self.data.extend( + render::ui::UIElement::new( + &texture.relative(2.0 / 200.0, 0.0, 196.0 / 200.0, 2.0 / 20.0), + r.x + 4.0 * sw, + r.y, + r.w - 8.0 * sw, + 4.0 * sh, + 0.0, + 0.0, + w / 196.0, + 1.0, + ) + .bytes(width, height), ); - self.data.extend(render::ui::UIElement::new( - &texture.relative(198.0/200.0, 2.0/20.0, 2.0/200.0, 15.0/20.0), - r.x+r.w - 4.0 * sw, r.y + 4.0*sh, 4.0 * sw, r.h - 10.0*sh, 0.0, 0.0, 1.0, h/16.0).bytes(width, height) + self.data.extend( + render::ui::UIElement::new( + &texture.relative(2.0 / 200.0, 17.0 / 20.0, 196.0 / 200.0, 3.0 / 20.0), + r.x + 4.0 * sw, + r.y + r.h - 6.0 * sh, + r.w - 8.0 * sw, + 6.0 * sh, + 0.0, + 0.0, + w / 196.0, + 1.0, + ) + .bytes(width, height), ); + let h = ((r.h / sh) / 2.0) - 5.0; + self.data.extend( + render::ui::UIElement::new( + &texture.relative(0.0 / 200.0, 2.0 / 20.0, 2.0 / 200.0, 15.0 / 20.0), + r.x, + r.y + 4.0 * sh, + 4.0 * sw, + r.h - 10.0 * sh, + 0.0, + 0.0, + 1.0, + h / 16.0, + ) + .bytes(width, height), + ); + self.data.extend( + render::ui::UIElement::new( + &texture.relative(198.0 / 200.0, 2.0 / 20.0, 2.0 / 200.0, 15.0 / 20.0), + r.x + r.w - 4.0 * sw, + r.y + 4.0 * sh, + 4.0 * sw, + r.h - 10.0 * sh, + 0.0, + 0.0, + 1.0, + h / 16.0, + ) + .bytes(width, height), + ); - self.data.extend(render::ui::UIElement::new( - &texture.relative(2.0/200.0, 2.0/20.0, 196.0/200.0, 15.0/20.0), - r.x+4.0*sw, r.y+4.0*sh, r.w - 8.0 * sw, r.h - 10.0 * sh, 0.0, 0.0, w/196.0, h/16.0).bytes(width, height) + self.data.extend( + render::ui::UIElement::new( + &texture.relative(2.0 / 200.0, 2.0 / 20.0, 196.0 / 200.0, 15.0 / 20.0), + r.x + 4.0 * sw, + r.y + 4.0 * sh, + r.w - 8.0 * sw, + r.h - 10.0 * sh, + 0.0, + 0.0, + w / 196.0, + h / 16.0, + ) + .bytes(width, height), ); self.super_draw(renderer, r, sw, sh, width, height, delta); self.last_disabled = self.disabled; @@ -1254,11 +1452,9 @@ impl UIElement for Button { } fn is_dirty(&self) -> bool { - self.last_disabled != self.disabled - || self.last_hovered != self.hovered + self.last_disabled != self.disabled || self.last_hovered != self.hovered } - fn post_init(s: Rc>) { s.borrow_mut().add_hover_func(move |this, hover, _| { this.hovered = hover; @@ -1311,9 +1507,17 @@ impl TextBoxBuilder { } impl UIElement for TextBox { - fn key_press(&mut self, game: &mut crate::Game, key: VirtualKeyCode, down: bool, ctrl_pressed: bool) { + fn key_press( + &mut self, + game: &mut crate::Game, + key: VirtualKeyCode, + down: bool, + ctrl_pressed: bool, + ) { match (key, down) { - (VirtualKeyCode::Back, _) => {self.input.pop();}, + (VirtualKeyCode::Back, _) => { + self.input.pop(); + } (VirtualKeyCode::Return, false) => { use std::mem; let len = self.submit_funcs.len(); @@ -1322,7 +1526,7 @@ impl UIElement for TextBox { (func)(self, game); } self.submit_funcs.append(&mut temp); - }, + } // TODO: wasm clipboard pasting, Clipboard API: https://www.w3.org/TR/clipboard-apis/ #[cfg(not(target_arch = "wasm32"))] (VirtualKeyCode::V, true) => { @@ -1330,11 +1534,11 @@ impl UIElement for TextBox { let mut clipboard: ClipboardContext = ClipboardProvider::new().unwrap(); match clipboard.get_contents() { Ok(text) => self.input.push_str(&text), - Err(_) => () + Err(_) => (), } } - }, - _ => {}, + } + _ => {} } } @@ -1342,7 +1546,16 @@ impl UIElement for TextBox { self.input.push(c); } - fn draw(&mut self, renderer: &mut render::Renderer, r: &Region, sw: f64, sh: f64, width: f64, height: f64, delta: f64) -> &mut [u8] { + fn draw( + &mut self, + renderer: &mut render::Renderer, + r: &Region, + sw: f64, + sh: f64, + width: f64, + height: f64, + delta: f64, + ) -> &mut [u8] { if self.check_rebuild() { self.data.clear(); self.cursor_tick += delta; @@ -1381,17 +1594,21 @@ impl UIElement for TextBox { fn post_init(s: Rc>) { let mut textbox = s.borrow_mut(); - textbox.button = Some(ButtonBuilder::new() - .position(0.0, 0.0) - .size(textbox.width, textbox.height) - .disabled(true) - .attach(&mut *textbox)); - textbox.text = Some(TextBuilder::new() - .text("") - .position(5.0, 0.0) - .draw_index(1) - .alignment(VAttach::Middle, HAttach::Left) - .attach(&mut *textbox)); + textbox.button = Some( + ButtonBuilder::new() + .position(0.0, 0.0) + .size(textbox.width, textbox.height) + .disabled(true) + .attach(&mut *textbox), + ); + textbox.text = Some( + TextBuilder::new() + .text("") + .position(5.0, 0.0) + .draw_index(1) + .alignment(VAttach::Middle, HAttach::Left) + .attach(&mut *textbox), + ); } } diff --git a/src/world/biome.rs b/src/world/biome.rs index 9e1c3df..ea3e999 100644 --- a/src/world/biome.rs +++ b/src/world/biome.rs @@ -1,4 +1,3 @@ - use image::Rgba; use lazy_static::lazy_static; @@ -14,7 +13,7 @@ impl Biome { Biome { id, temperature: t, - moisture: m*t, + moisture: m * t, } } @@ -23,21 +22,19 @@ impl Biome { } pub fn get_color_index(self) -> usize { - let t = (self.temperature as f64 / 100f64) .min(1.0).max(0.0); + let t = (self.temperature as f64 / 100f64).min(1.0).max(0.0); let m = (self.moisture as f64 / 100f64).min(1.0).max(0.0); - (((1.0 - t) * 255.0) as usize) | ((((1.0 - (m*t)) * 255.0) as usize) << 8) + (((1.0 - t) * 255.0) as usize) | ((((1.0 - (m * t)) * 255.0) as usize) << 8) } pub fn process_color(self, col: Rgba) -> Rgba { if self.id == ROOFED_FOREST.id || self.id == ROOFED_FOREST_MOUNTAINS.id { - Rgba ( - [ - ((col.0[0] as u32 + 0x28) / 2) as u8, - ((col.0[1] as u32 + 0x34) / 2) as u8, - ((col.0[2] as u32 + 0x0A) / 2) as u8, - 255 - ] - ) + Rgba([ + ((col.0[0] as u32 + 0x28) / 2) as u8, + ((col.0[1] as u32 + 0x34) / 2) as u8, + ((col.0[2] as u32 + 0x0A) / 2) as u8, + 255, + ]) } else { col } diff --git a/src/world/mod.rs b/src/world/mod.rs index df0a2a6..cdb4d23 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -14,21 +14,21 @@ pub use steven_blocks as block; -use std::collections::HashMap; -use std::collections::VecDeque; -use std::hash::BuildHasherDefault; -use crate::types::{bit, nibble}; -use crate::shared::{Position, Direction}; -use crate::types::hash::FNVHash; -use crate::protocol; -use crate::render; -use collision; -use cgmath::prelude::*; use crate::chunk_builder; use crate::ecs; use crate::entity::block_entity; use crate::format; +use crate::protocol; +use crate::render; +use crate::shared::{Direction, Position}; +use crate::types::hash::FNVHash; +use crate::types::{bit, nibble}; +use cgmath::prelude::*; +use collision; use flate2::read::ZlibDecoder; +use std::collections::HashMap; +use std::collections::VecDeque; +use std::hash::BuildHasherDefault; use std::io::Read; pub mod biome; @@ -52,13 +52,19 @@ pub struct World { pub enum BlockEntityAction { Create(Position), Remove(Position), - UpdateSignText(Position, format::Component, format::Component, format::Component, format::Component), + UpdateSignText( + Position, + format::Component, + format::Component, + format::Component, + format::Component, + ), } #[derive(Clone, Copy, PartialEq, Eq)] enum LightType { Block, - Sky + Sky, } impl LightType { @@ -104,10 +110,12 @@ impl World { let chunk = self.chunks.entry(cpos).or_insert_with(|| Chunk::new(cpos)); if chunk.set_block(pos.x & 0xF, pos.y, pos.z & 0xF, b) { if chunk.block_entities.contains_key(&pos) { - self.block_entity_actions.push_back(BlockEntityAction::Remove(pos)); + self.block_entity_actions + .push_back(BlockEntityAction::Remove(pos)); } if block_entity::BlockEntityType::get_block_entity(b).is_some() { - self.block_entity_actions.push_back(BlockEntityAction::Create(pos)); + self.block_entity_actions + .push_back(BlockEntityAction::Create(pos)); } true } else { @@ -116,9 +124,9 @@ impl World { } pub fn update_block(&mut self, pos: Position) { - for yy in -1 .. 2 { - for zz in -1 .. 2 { - for xx in -1 .. 2 { + for yy in -1..2 { + for zz in -1..2 { + for xx in -1..2 { let bp = pos + (xx, yy, zz); let current = self.get_block(bp); let new = current.update_state(self, bp); @@ -134,9 +142,9 @@ impl World { } fn update_range(&mut self, x1: i32, y1: i32, z1: i32, x2: i32, y2: i32, z2: i32) { - for by in y1 .. y2 { - for bz in z1 .. z2 { - for bx in x1 .. x2 { + for by in y1..y2 { + for bz in z1..z2 { + for bx in x1..x2 { let bp = Position::new(bx, by, bz); let current = self.get_block(bp); let new = current.update_state(self, bp); @@ -156,7 +164,7 @@ impl World { pub fn get_block(&self, pos: Position) -> block::Block { match self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) { Some(chunk) => chunk.get_block(pos.x & 0xF, pos.y, pos.z & 0xF), - None => block::Missing{}, + None => block::Missing {}, } } @@ -187,10 +195,7 @@ impl World { } fn update_light(&mut self, pos: Position, ty: LightType) { - self.light_updates.push_back(LightUpdate { - ty, - pos, - }); + self.light_updates.push_back(LightUpdate { ty, pos }); } pub fn add_block_entity_action(&mut self, action: BlockEntityAction) { @@ -198,14 +203,15 @@ impl World { } pub fn tick(&mut self, m: &mut ecs::Manager) { - use std::time::{Instant}; + use std::time::Instant; let start = Instant::now(); let mut updates_performed = 0; while !self.light_updates.is_empty() { updates_performed += 1; self.do_light_update(); if updates_performed & 0xFFF == 0 { - if start.elapsed().subsec_nanos() >= 5000000 { // 5 ms for light updates + if start.elapsed().subsec_nanos() >= 5000000 { + // 5 ms for light updates break; } } @@ -221,7 +227,7 @@ impl World { m.remove_entity(entity); } } - }, + } BlockEntityAction::Create(pos) => { if let Some(chunk) = self.chunks.get_mut(&CPos(pos.x >> 4, pos.z >> 4)) { // Remove existing entity @@ -229,22 +235,19 @@ impl World { m.remove_entity(entity); } let block = chunk.get_block(pos.x & 0xF, pos.y, pos.z & 0xF); - if let Some(entity_type) = block_entity::BlockEntityType::get_block_entity(block) { + if let Some(entity_type) = + block_entity::BlockEntityType::get_block_entity(block) + { let entity = entity_type.create_entity(m, pos); chunk.block_entities.insert(pos, entity); } } - }, + } BlockEntityAction::UpdateSignText(pos, line1, line2, line3, line4) => { if let Some(chunk) = self.chunks.get(&CPos(pos.x >> 4, pos.z >> 4)) { if let Some(entity) = chunk.block_entities.get(&pos) { if let Some(sign) = m.get_component_mut(*entity, sign_info) { - sign.lines = [ - line1, - line2, - line3, - line4, - ]; + sign.lines = [line1, line2, line3, line4]; sign.dirty = true; } } @@ -257,7 +260,10 @@ impl World { fn do_light_update(&mut self) { use std::cmp; if let Some(update) = self.light_updates.pop_front() { - if update.pos.y < 0 || update.pos.y > 255 || !self.is_chunk_loaded(update.pos.x >> 4, update.pos.z >> 4) { + if update.pos.y < 0 + || update.pos.y > 255 + || !self.is_chunk_loaded(update.pos.x >> 4, update.pos.z >> 4) + { return; } @@ -280,7 +286,8 @@ impl World { // Sky light doesn't decrease when going down at full brightness if update.ty == LightType::Sky && block.absorbed_light == 0 - && update.ty.get_light(self, update.pos.shift(Direction::Up)) == 15 { + && update.ty.get_light(self, update.pos.shift(Direction::Up)) == 15 + { best = 15; } @@ -291,9 +298,9 @@ impl World { // Use our new light value update.ty.set_light(self, update.pos, best); // Flag surrounding chunks as dirty - for yy in -1 .. 2 { - for zz in -1 .. 2 { - for xx in -1 .. 2 { + for yy in -1..2 { + for zz in -1..2 { + for xx in -1..2 { let bp = update.pos + (xx, yy, zz); self.set_dirty(bp.x >> 4, bp.y >> 4, bp.z >> 4); } @@ -313,12 +320,11 @@ impl World { if c.heightmap_dirty { dirty = true; c.heightmap_dirty = false; - for xx in 0 .. 16 { - for zz in 0 .. 16 { - data[ - (((c.position.0 << 4) as usize + xx) & 0x1FF) + - ((((c.position.1 << 4) as usize + zz) & 0x1FF) << 9) - ] = c.heightmap[(zz << 4) | xx]; + for xx in 0..16 { + for zz in 0..16 { + data[(((c.position.0 << 4) as usize + xx) & 0x1FF) + + ((((c.position.1 << 4) as usize + zz) & 0x1FF) << 9)] = + c.heightmap[(zz << 4) | xx]; } } } @@ -339,25 +345,37 @@ impl World { let start = ( ((renderer.camera.pos.x as i32) >> 4), ((renderer.camera.pos.y as i32) >> 4), - ((renderer.camera.pos.z as i32) >> 4) + ((renderer.camera.pos.z as i32) >> 4), ); let mut process_queue = VecDeque::with_capacity(self.chunks.len() * 16); process_queue.push_front((Direction::Invalid, start)); while let Some((from, pos)) = process_queue.pop_front() { - let (exists, cull) = if let Some((sec, rendered_on)) = self.get_render_section_mut(pos.0, pos.1, pos.2) { + let (exists, cull) = if let Some((sec, rendered_on)) = + self.get_render_section_mut(pos.0, pos.1, pos.2) + { if *rendered_on == renderer.frame_id { continue; } *rendered_on = renderer.frame_id; - let min = cgmath::Point3::new(pos.0 as f32 * 16.0, -pos.1 as f32 * 16.0, pos.2 as f32 * 16.0); - let bounds = collision::Aabb3::new(min, min + cgmath::Vector3::new(16.0, -16.0, 16.0)); - if renderer.frustum.contains(&bounds) == collision::Relation::Out && from != Direction::Invalid { + let min = cgmath::Point3::new( + pos.0 as f32 * 16.0, + -pos.1 as f32 * 16.0, + pos.2 as f32 * 16.0, + ); + let bounds = + collision::Aabb3::new(min, min + cgmath::Vector3::new(16.0, -16.0, 16.0)); + if renderer.frustum.contains(&bounds) == collision::Relation::Out + && from != Direction::Invalid + { continue; } - (sec.is_some(), sec.map_or(chunk_builder::CullInfo::all_vis(), |v| v.cull_info)) + ( + sec.is_some(), + sec.map_or(chunk_builder::CullInfo::all_vis(), |v| v.cull_info), + ) } else { continue; }; @@ -369,11 +387,14 @@ impl World { for dir in Direction::all() { let (ox, oy, oz) = dir.get_offset(); let opos = (pos.0 + ox, pos.1 + oy, pos.2 + oz); - if let Some((_, rendered_on)) = self.get_render_section_mut(opos.0, opos.1, opos.2) { + if let Some((_, rendered_on)) = self.get_render_section_mut(opos.0, opos.1, opos.2) + { if *rendered_on == renderer.frame_id { continue; } - if from == Direction::Invalid || (valid_dirs[dir.index()] && cull.is_visible(from, dir)) { + if from == Direction::Invalid + || (valid_dirs[dir.index()] && cull.is_visible(from, dir)) + { process_queue.push_back((dir.opposite(), opos)); } } @@ -382,11 +403,14 @@ impl World { } pub fn get_render_list(&self) -> Vec<((i32, i32, i32), &render::ChunkBuffer)> { - self.render_list.iter().map(|v| { - let chunk = self.chunks.get(&CPos(v.0, v.2)).unwrap(); - let sec = chunk.sections[v.1 as usize].as_ref().unwrap(); - (*v, &sec.render_buffer) - }).collect() + self.render_list + .iter() + .map(|v| { + let chunk = self.chunks.get(&CPos(v.0, v.2)).unwrap(); + let sec = chunk.sections[v.1 as usize].as_ref().unwrap(); + (*v, &sec.render_buffer) + }) + .collect() } pub fn get_section_mut(&mut self, x: i32, y: i32, z: i32) -> Option<&mut Section> { @@ -398,7 +422,12 @@ impl World { None } - fn get_render_section_mut(&mut self, x: i32, y: i32, z: i32) -> Option<(Option<&mut Section>, &mut u32)> { + fn get_render_section_mut( + &mut self, + x: i32, + y: i32, + z: i32, + ) -> Option<(Option<&mut Section>, &mut u32)> { if y < 0 || y > 15 { return None; } @@ -471,17 +500,21 @@ impl World { } pub fn capture_snapshot(&self, x: i32, y: i32, z: i32, w: i32, h: i32, d: i32) -> Snapshot { - use std::cmp::{min, max}; + use std::cmp::{max, min}; let mut snapshot = Snapshot { - blocks: storage::BlockStorage::new_default((w * h * d) as usize, block::Missing{}), + blocks: storage::BlockStorage::new_default((w * h * d) as usize, block::Missing {}), block_light: nibble::Array::new((w * h * d) as usize), sky_light: nibble::Array::new((w * h * d) as usize), biomes: vec![0; (w * d) as usize], - x, y, z, - w, _h: h, d, + x, + y, + z, + w, + _h: h, + d, }; - for i in 0 .. (w * h * d) as usize { + for i in 0..(w * h * d) as usize { snapshot.sky_light.set(i, 0xF); } @@ -492,48 +525,58 @@ impl World { let cy2 = (y + h + 15) >> 4; let cz2 = (z + d + 15) >> 4; - for cx in cx1 .. cx2 { - for cz in cz1 .. cz2 { + for cx in cx1..cx2 { + for cz in cz1..cz2 { let chunk = match self.chunks.get(&CPos(cx, cz)) { Some(val) => val, None => continue, }; - let x1 = min(16, max(0, x - (cx<<4))); - let x2 = min(16, max(0, x + w - (cx<<4))); - let z1 = min(16, max(0, z - (cz<<4))); - let z2 = min(16, max(0, z + d - (cz<<4))); + let x1 = min(16, max(0, x - (cx << 4))); + let x2 = min(16, max(0, x + w - (cx << 4))); + let z1 = min(16, max(0, z - (cz << 4))); + let z2 = min(16, max(0, z + d - (cz << 4))); - for cy in cy1 .. cy2 { + for cy in cy1..cy2 { if cy < 0 || cy > 15 { continue; } let section = &chunk.sections[cy as usize]; - let y1 = min(16, max(0, y - (cy<<4))); - let y2 = min(16, max(0, y + h - (cy<<4))); + let y1 = min(16, max(0, y - (cy << 4))); + let y2 = min(16, max(0, y + h - (cy << 4))); - for yy in y1 .. y2 { - for zz in z1 .. z2 { - for xx in x1 .. x2 { + for yy in y1..y2 { + for zz in z1..z2 { + for xx in x1..x2 { let ox = xx + (cx << 4); let oy = yy + (cy << 4); let oz = zz + (cz << 4); match section.as_ref() { Some(sec) => { snapshot.set_block(ox, oy, oz, sec.get_block(xx, yy, zz)); - snapshot.set_block_light(ox, oy, oz, sec.get_block_light(xx, yy, zz)); - snapshot.set_sky_light(ox, oy, oz, sec.get_sky_light(xx, yy, zz)); - }, + snapshot.set_block_light( + ox, + oy, + oz, + sec.get_block_light(xx, yy, zz), + ); + snapshot.set_sky_light( + ox, + oy, + oz, + sec.get_sky_light(xx, yy, zz), + ); + } None => { - snapshot.set_block(ox, oy, oz, block::Air{}); - }, + snapshot.set_block(ox, oy, oz, block::Air {}); + } } } } } } - for zz in z1 .. z2 { - for xx in x1 .. x2 { + for zz in z1..z2 { + for xx in x1..x2 { let ox = xx + (cx << 4); let oz = zz + (cz << 4); snapshot.set_biome(ox, oz, chunk.get_biome(xx, zz)); @@ -553,38 +596,62 @@ impl World { } } - pub fn load_chunks18(&mut self, new: bool, skylight: bool, chunk_metas: &[crate::protocol::packet::ChunkMeta], data: Vec) -> Result<(), protocol::Error> { - let mut data = std::io::Cursor::new(data); + pub fn load_chunks18( + &mut self, + new: bool, + skylight: bool, + chunk_metas: &[crate::protocol::packet::ChunkMeta], + data: Vec, + ) -> Result<(), protocol::Error> { + let mut data = std::io::Cursor::new(data); - for chunk_meta in chunk_metas { - let x = chunk_meta.x; - let z = chunk_meta.z; - let mask = chunk_meta.bitmask; + for chunk_meta in chunk_metas { + let x = chunk_meta.x; + let z = chunk_meta.z; + let mask = chunk_meta.bitmask; - self.load_chunk18(x, z, new, skylight, mask, &mut data)?; - } - Ok(()) + self.load_chunk18(x, z, new, skylight, mask, &mut data)?; + } + Ok(()) } fn dirty_chunks_by_bitmask(&mut self, x: i32, z: i32, mask: u16) { - for i in 0 .. 16 { + for i in 0..16 { if mask & (1 << i) == 0 { continue; } for pos in [ - (-1, 0, 0), (1, 0, 0), - (0, -1, 0), (0, 1, 0), - (0, 0, -1), (0, 0, 1)].iter() { + (-1, 0, 0), + (1, 0, 0), + (0, -1, 0), + (0, 1, 0), + (0, 0, -1), + (0, 0, 1), + ] + .iter() + { self.flag_section_dirty(x + pos.0, i as i32 + pos.1, z + pos.2); } self.update_range( - (x<<4) - 1, (i<<4) - 1, (z<<4) - 1, - (x<<4) + 17, (i<<4) + 17, (z<<4) + 17 + (x << 4) - 1, + (i << 4) - 1, + (z << 4) - 1, + (x << 4) + 17, + (i << 4) + 17, + (z << 4) + 17, ); } } - pub fn load_chunk18(&mut self, x: i32, z: i32, new: bool, _skylight: bool, mask: u16, data: &mut std::io::Cursor>) -> Result<(), protocol::Error> { + pub fn load_chunk18( + &mut self, + x: i32, + z: i32, + new: bool, + _skylight: bool, + mask: u16, + data: &mut std::io::Cursor>, + ) -> Result<(), protocol::Error> { use byteorder::ReadBytesExt; let cpos = CPos(x, z); @@ -599,11 +666,9 @@ impl World { self.chunks.get_mut(&cpos).unwrap() }; - for i in 0 .. 16 { + for i in 0..16 { if chunk.sections[i].is_none() { - let mut fill_sky = chunk.sections.iter() - .skip(i) - .all(|v| v.is_none()); + let mut fill_sky = chunk.sections.iter().skip(i).all(|v| v.is_none()); fill_sky &= (mask & !((1 << i) | ((1 << i) - 1))) == 0; if !fill_sky || mask & (1 << i) != 0 { chunk.sections[i] = Some(Section::new(i as u8, fill_sky)); @@ -615,9 +680,16 @@ impl World { let section = chunk.sections[i as usize].as_mut().unwrap(); section.dirty = true; - for bi in 0 .. 4096 { + for bi in 0..4096 { let id = data.read_u16::()?; - section.blocks.set(bi, block::Block::by_vanilla_id(id as usize, self.protocol_version, &self.modded_block_ids)); + section.blocks.set( + bi, + block::Block::by_vanilla_id( + id as usize, + self.protocol_version, + &self.modded_block_ids, + ), + ); // Spawn block entities let b = section.blocks.get(bi); @@ -625,17 +697,23 @@ impl World { let pos = Position::new( (bi & 0xF) as i32, (bi >> 8) as i32, - ((bi >> 4) & 0xF) as i32 - ) + (chunk.position.0 << 4, (i << 4) as i32, chunk.position.1 << 4); + ((bi >> 4) & 0xF) as i32, + ) + ( + chunk.position.0 << 4, + (i << 4) as i32, + chunk.position.1 << 4, + ); if chunk.block_entities.contains_key(&pos) { - self.block_entity_actions.push_back(BlockEntityAction::Remove(pos)) + self.block_entity_actions + .push_back(BlockEntityAction::Remove(pos)) } - self.block_entity_actions.push_back(BlockEntityAction::Create(pos)) + self.block_entity_actions + .push_back(BlockEntityAction::Create(pos)) } } } - for i in 0 .. 16 { + for i in 0..16 { if mask & (1 << i) == 0 { continue; } @@ -644,7 +722,7 @@ impl World { data.read_exact(&mut section.block_light.data)?; } - for i in 0 .. 16 { + for i in 0..16 { if mask & (1 << i) == 0 { continue; } @@ -664,7 +742,13 @@ impl World { Ok(()) } - pub fn load_chunks17(&mut self, chunk_column_count: u16, data_length: i32, skylight: bool, data: &[u8]) -> Result<(), protocol::Error> { + pub fn load_chunks17( + &mut self, + chunk_column_count: u16, + data_length: i32, + skylight: bool, + data: &[u8], + ) -> Result<(), protocol::Error> { let compressed_chunk_data = &data[0..data_length as usize]; let metadata = &data[data_length as usize..]; @@ -692,16 +776,41 @@ impl World { Ok(()) } - pub fn load_chunk17(&mut self, x: i32, z: i32, new: bool, mask: u16, mask_add: u16, compressed_data: Vec) -> Result<(), protocol::Error> { - let mut zlib = ZlibDecoder::new(std::io::Cursor::new(compressed_data.to_vec())); - let mut data = Vec::new(); - zlib.read_to_end(&mut data)?; + pub fn load_chunk17( + &mut self, + x: i32, + z: i32, + new: bool, + mask: u16, + mask_add: u16, + compressed_data: Vec, + ) -> Result<(), protocol::Error> { + let mut zlib = ZlibDecoder::new(std::io::Cursor::new(compressed_data.to_vec())); + let mut data = Vec::new(); + zlib.read_to_end(&mut data)?; - let skylight = true; - self.load_uncompressed_chunk17(x, z, new, skylight, mask, mask_add, &mut std::io::Cursor::new(data)) + let skylight = true; + self.load_uncompressed_chunk17( + x, + z, + new, + skylight, + mask, + mask_add, + &mut std::io::Cursor::new(data), + ) } - fn load_uncompressed_chunk17(&mut self, x: i32, z: i32, new: bool, skylight: bool, mask: u16, mask_add: u16, data: &mut std::io::Cursor>) -> Result<(), protocol::Error> { + fn load_uncompressed_chunk17( + &mut self, + x: i32, + z: i32, + new: bool, + skylight: bool, + mask: u16, + mask_add: u16, + data: &mut std::io::Cursor>, + ) -> Result<(), protocol::Error> { let cpos = CPos(x, z); { let chunk = if new { @@ -716,11 +825,9 @@ impl World { // Block type array - whole byte per block let mut block_types = [[0u8; 4096]; 16]; - for i in 0 .. 16 { + for i in 0..16 { if chunk.sections[i].is_none() { - let mut fill_sky = chunk.sections.iter() - .skip(i) - .all(|v| v.is_none()); + let mut fill_sky = chunk.sections.iter().skip(i).all(|v| v.is_none()); fill_sky &= (mask & !((1 << i) | ((1 << i) - 1))) == 0; if !fill_sky || mask & (1 << i) != 0 { chunk.sections[i] = Some(Section::new(i as u8, fill_sky)); @@ -738,13 +845,25 @@ impl World { // Block metadata array - half byte per block let mut block_meta: [nibble::Array; 16] = [ // TODO: cleanup this initialization - nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), - nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), - nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), - nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), ]; - for i in 0 .. 16 { + for i in 0..16 { if mask & (1 << i) == 0 { continue; } @@ -753,7 +872,7 @@ impl World { } // Block light array - half byte per block - for i in 0 .. 16 { + for i in 0..16 { if mask & (1 << i) == 0 { continue; } @@ -764,7 +883,7 @@ impl World { // Sky light array - half byte per block - only if 'skylight' is true if skylight { - for i in 0 .. 16 { + for i in 0..16 { if mask & (1 << i) == 0 { continue; } @@ -777,13 +896,25 @@ impl World { // Add array - half byte per block - uses secondary bitmask let mut block_add: [nibble::Array; 16] = [ // TODO: cleanup this initialization - nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), - nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), - nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), - nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), + nibble::Array::new(16 * 16 * 16), ]; - for i in 0 .. 16 { + for i in 0..16 { if mask_add & (1 << i) == 0 { continue; } @@ -791,16 +922,25 @@ impl World { } // Now that we have the block types, metadata, and add, combine to initialize the blocks - for i in 0 .. 16 { + for i in 0..16 { if mask & (1 << i) == 0 { continue; } let section = chunk.sections[i as usize].as_mut().unwrap(); - for bi in 0 .. 4096 { - let id = ((block_add[i].get(bi) as u16) << 12) | ((block_types[i][bi] as u16) << 4) | (block_meta[i].get(bi) as u16); - section.blocks.set(bi, block::Block::by_vanilla_id(id as usize, self.protocol_version, &self.modded_block_ids)); + for bi in 0..4096 { + let id = ((block_add[i].get(bi) as u16) << 12) + | ((block_types[i][bi] as u16) << 4) + | (block_meta[i].get(bi) as u16); + section.blocks.set( + bi, + block::Block::by_vanilla_id( + id as usize, + self.protocol_version, + &self.modded_block_ids, + ), + ); // Spawn block entities let b = section.blocks.get(bi); @@ -808,12 +948,18 @@ impl World { let pos = Position::new( (bi & 0xF) as i32, (bi >> 8) as i32, - ((bi >> 4) & 0xF) as i32 - ) + (chunk.position.0 << 4, (i << 4) as i32, chunk.position.1 << 4); + ((bi >> 4) & 0xF) as i32, + ) + ( + chunk.position.0 << 4, + (i << 4) as i32, + chunk.position.1 << 4, + ); if chunk.block_entities.contains_key(&pos) { - self.block_entity_actions.push_back(BlockEntityAction::Remove(pos)) + self.block_entity_actions + .push_back(BlockEntityAction::Remove(pos)) } - self.block_entity_actions.push_back(BlockEntityAction::Create(pos)) + self.block_entity_actions + .push_back(BlockEntityAction::Create(pos)) } } } @@ -829,18 +975,40 @@ impl World { Ok(()) } - pub fn load_chunk19(&mut self, x: i32, z: i32, new: bool, mask: u16, data: Vec) -> Result<(), protocol::Error> { + pub fn load_chunk19( + &mut self, + x: i32, + z: i32, + new: bool, + mask: u16, + data: Vec, + ) -> Result<(), protocol::Error> { self.load_chunk19_or_115(true, x, z, new, mask, data) } - pub fn load_chunk115(&mut self, x: i32, z: i32, new: bool, mask: u16, data: Vec) -> Result<(), protocol::Error> { + pub fn load_chunk115( + &mut self, + x: i32, + z: i32, + new: bool, + mask: u16, + data: Vec, + ) -> Result<(), protocol::Error> { self.load_chunk19_or_115(false, x, z, new, mask, data) } - fn load_chunk19_or_115(&mut self, read_biomes: bool, x: i32, z: i32, new: bool, mask: u16, data: Vec) -> Result<(), protocol::Error> { - use std::io::Cursor; + fn load_chunk19_or_115( + &mut self, + read_biomes: bool, + x: i32, + z: i32, + new: bool, + mask: u16, + data: Vec, + ) -> Result<(), protocol::Error> { + use crate::protocol::{LenPrefixed, Serializable, VarInt}; use byteorder::ReadBytesExt; - use crate::protocol::{VarInt, Serializable, LenPrefixed}; + use std::io::Cursor; let mut data = Cursor::new(data); @@ -856,11 +1024,9 @@ impl World { self.chunks.get_mut(&cpos).unwrap() }; - for i in 0 .. 16 { + for i in 0..16 { if chunk.sections[i].is_none() { - let mut fill_sky = chunk.sections.iter() - .skip(i) - .all(|v| v.is_none()); + let mut fill_sky = chunk.sections.iter().skip(i).all(|v| v.is_none()); fill_sky &= (mask & !((1 << i) | ((1 << i) - 1))) == 0; if !fill_sky || mask & (1 << i) != 0 { chunk.sections[i] = Some(Section::new(i as u8, fill_sky)); @@ -871,21 +1037,26 @@ impl World { } let section = chunk.sections[i as usize].as_mut().unwrap(); section.dirty = true; - + if self.protocol_version >= 451 { let _block_count = data.read_u16::()?; // TODO: use block_count } let mut bit_size = data.read_u8()?; - let mut mappings: HashMap> = HashMap::with_hasher(BuildHasherDefault::default()); + let mut mappings: HashMap> = + HashMap::with_hasher(BuildHasherDefault::default()); if bit_size == 0 { bit_size = 13; } else { let count = VarInt::read_from(&mut data)?.0; - for i in 0 .. count { + for i in 0..count { let id = VarInt::read_from(&mut data)?.0; - let bl = block::Block::by_vanilla_id(id as usize, self.protocol_version, &self.modded_block_ids); + let bl = block::Block::by_vanilla_id( + id as usize, + self.protocol_version, + &self.modded_block_ids, + ); mappings.insert(i as usize, bl); } } @@ -893,21 +1064,37 @@ impl World { let bits = LenPrefixed::::read_from(&mut data)?.data; let m = bit::Map::from_raw(bits, bit_size as usize); - for bi in 0 .. 4096 { + for bi in 0..4096 { let id = m.get(bi); - section.blocks.set(bi, mappings.get(&id).cloned().unwrap_or(block::Block::by_vanilla_id(id, self.protocol_version, &self.modded_block_ids))); + section.blocks.set( + bi, + mappings + .get(&id) + .cloned() + .unwrap_or(block::Block::by_vanilla_id( + id, + self.protocol_version, + &self.modded_block_ids, + )), + ); // Spawn block entities let b = section.blocks.get(bi); if block_entity::BlockEntityType::get_block_entity(b).is_some() { let pos = Position::new( (bi & 0xF) as i32, (bi >> 8) as i32, - ((bi >> 4) & 0xF) as i32 - ) + (chunk.position.0 << 4, (i << 4) as i32, chunk.position.1 << 4); + ((bi >> 4) & 0xF) as i32, + ) + ( + chunk.position.0 << 4, + (i << 4) as i32, + chunk.position.1 << 4, + ); if chunk.block_entities.contains_key(&pos) { - self.block_entity_actions.push_back(BlockEntityAction::Remove(pos)) + self.block_entity_actions + .push_back(BlockEntityAction::Remove(pos)) } - self.block_entity_actions.push_back(BlockEntityAction::Create(pos)) + self.block_entity_actions + .push_back(BlockEntityAction::Create(pos)) } } @@ -964,7 +1151,6 @@ pub struct Snapshot { } impl Snapshot { - pub fn make_relative(&mut self, x: i32, y: i32, z: i32) { self.x = x; self.y = y; @@ -1033,10 +1219,8 @@ impl Chunk { Chunk { position: pos, sections: [ - None,None,None,None, - None,None,None,None, - None,None,None,None, - None,None,None,None, + None, None, None, None, None, None, None, None, None, None, None, None, None, None, + None, None, ], sections_rendered_on: [0; 16], biomes: [0; 16 * 16], @@ -1047,13 +1231,13 @@ impl Chunk { } fn calculate_heightmap(&mut self) { - for x in 0 .. 16 { - for z in 0 .. 16 { - let idx = ((z<<4)|x) as usize; - for yy in 0 .. 256 { + for x in 0..16 { + for z in 0..16 { + let idx = ((z << 4) | x) as usize; + for yy in 0..256 { let sy = 255 - yy; - if let block::Air{..} = self.get_block(x, sy, z) { - continue + if let block::Air { .. } = self.get_block(x, sy, z) { + continue; } self.heightmap[idx] = sy as u8; break; @@ -1073,9 +1257,7 @@ impl Chunk { if let block::Air {} = b { return false; } - let fill_sky = self.sections.iter() - .skip(s_idx) - .all(|v| v.is_none()); + let fill_sky = self.sections.iter().skip(s_idx).all(|v| v.is_none()); self.sections[s_idx] = Some(Section::new(s_idx as u8, fill_sky)); } { @@ -1084,16 +1266,16 @@ impl Chunk { return false; } } - let idx = ((z<<4)|x) as usize; + let idx = ((z << 4) | x) as usize; if self.heightmap[idx] < y as u8 { self.heightmap[idx] = y as u8; self.heightmap_dirty = true; } else if self.heightmap[idx] == y as u8 { // Find a new lowest - for yy in 0 .. y { + for yy in 0..y { let sy = y - yy - 1; - if let block::Air{..} = self.get_block(x, sy, z) { - continue + if let block::Air { .. } = self.get_block(x, sy, z) { + continue; } self.heightmap[idx] = sy as u8; break; @@ -1106,11 +1288,11 @@ impl Chunk { fn get_block(&self, x: i32, y: i32, z: i32) -> block::Block { let s_idx = y >> 4; if s_idx < 0 || s_idx > 15 { - return block::Missing{}; + return block::Missing {}; } match self.sections[s_idx as usize].as_ref() { Some(sec) => sec.get_block(x, y & 0xF, z), - None => block::Air{}, + None => block::Air {}, } } @@ -1135,9 +1317,7 @@ impl Chunk { if light == 0 { return; } - let fill_sky = self.sections.iter() - .skip(s_idx) - .all(|v| v.is_none()); + let fill_sky = self.sections.iter().skip(s_idx).all(|v| v.is_none()); self.sections[s_idx] = Some(Section::new(s_idx as u8, fill_sky)); } if let Some(sec) = self.sections[s_idx].as_mut() { @@ -1166,9 +1346,7 @@ impl Chunk { if light == 15 { return; } - let fill_sky = self.sections.iter() - .skip(s_idx) - .all(|v| v.is_none()); + let fill_sky = self.sections.iter().skip(s_idx).all(|v| v.is_none()); self.sections[s_idx] = Some(Section::new(s_idx as u8, fill_sky)); } if let Some(sec) = self.sections[s_idx as usize].as_mut() { @@ -1177,7 +1355,7 @@ impl Chunk { } fn get_biome(&self, x: i32, z: i32) -> biome::Biome { - biome::Biome::by_id(self.biomes[((z<<4)|x) as usize] as usize) + biome::Biome::by_id(self.biomes[((z << 4) | x) as usize] as usize) } } @@ -1212,7 +1390,7 @@ impl Section { building: false, }; if fill_sky { - for i in 0 .. 16*16*16 { + for i in 0..16 * 16 * 16 { section.sky_light.set(i, 0xF); } } diff --git a/src/world/storage.rs b/src/world/storage.rs index e9cc244..312edff 100644 --- a/src/world/storage.rs +++ b/src/world/storage.rs @@ -1,4 +1,3 @@ - use crate::types::bit; use crate::types::hash::FNVHash; use crate::world::block; @@ -14,15 +13,13 @@ pub struct BlockStorage { impl BlockStorage { pub fn new(size: usize) -> BlockStorage { - Self::new_default(size, block::Air{}) + Self::new_default(size, block::Air {}) } pub fn new_default(size: usize, def: block::Block) -> BlockStorage { let mut storage = BlockStorage { blocks: bit::Map::new(size, 4), - block_map: vec![ - (def, size as u32) - ], + block_map: vec![(def, size as u32)], rev_block_map: HashMap::with_hasher(BuildHasherDefault::default()), }; storage.rev_block_map.insert(def, 0); @@ -45,7 +42,8 @@ impl BlockStorage { let idx = *self.rev_block_map.get(&old).unwrap(); let info = &mut self.block_map[idx]; info.1 -= 1; - if info.1 == 0 { // None left of this type + if info.1 == 0 { + // None left of this type self.rev_block_map.remove(&old); } }