From af2a01fad7bed20dfee2a870c8f32e7f90d039d4 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 01:28:09 +0100 Subject: [PATCH 001/160] empty commit to create pull request From 478930e37c26a8ce61dc2ce09391d7f460e759e0 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 01:46:22 +0100 Subject: [PATCH 002/160] restructure --- Cargo.toml | 53 ++++++------------ crabs.txt | 1 - kubi-server/Cargo.toml | 8 +++ kubi-server/src/main.rs | 3 + kubi-shared/Cargo.toml | 8 +++ kubi-shared/src/lib.rs | 14 +++++ kubi/Cargo.toml | 20 +++++++ README.md => kubi/README.md | 0 {assets => kubi/assets}/blocks/bedrock.png | Bin {assets => kubi/assets}/blocks/dirt.png | Bin {assets => kubi/assets}/blocks/grass_side.png | Bin .../assets}/blocks/grass_side_snow.png | Bin {assets => kubi/assets}/blocks/grass_top.png | Bin {assets => kubi/assets}/blocks/leaf.png | Bin {assets => kubi/assets}/blocks/sand.png | Bin {assets => kubi/assets}/blocks/snow.png | Bin {assets => kubi/assets}/blocks/stone.png | Bin {assets => kubi/assets}/blocks/tall_grass.png | Bin {assets => kubi/assets}/blocks/torch.png | Bin {assets => kubi/assets}/blocks/wood.png | Bin {assets => kubi/assets}/blocks/wood_top.png | Bin {shaders => kubi/shaders}/colored.frag | 0 {shaders => kubi/shaders}/colored.vert | 0 {shaders => kubi/shaders}/selection_box.frag | 0 {shaders => kubi/shaders}/selection_box.vert | 0 {shaders => kubi/shaders}/world.frag | 0 {shaders => kubi/shaders}/world.vert | 0 {src => kubi/src}/block_placement.rs | 0 {src => kubi/src}/camera.rs | 0 {src => kubi/src}/camera/frustum.rs | 0 {src => kubi/src}/camera/matrices.rs | 0 {src => kubi/src}/control_flow.rs | 0 {src => kubi/src}/cursor_lock.rs | 0 {src => kubi/src}/delta_time.rs | 0 {src => kubi/src}/events.rs | 0 {src => kubi/src}/events/player_actions.rs | 0 {src => kubi/src}/fly_controller.rs | 0 {src => kubi/src}/input.rs | 0 {src => kubi/src}/logging.rs | 0 {src => kubi/src}/main.rs | 0 {src => kubi/src}/player.rs | 0 {src => kubi/src}/prefabs.rs | 0 {src => kubi/src}/prefabs/shaders.rs | 0 {src => kubi/src}/prefabs/texture.rs | 0 {src => kubi/src}/rendering.rs | 0 {src => kubi/src}/rendering/primitives.rs | 0 {src => kubi/src}/rendering/selection_box.rs | 0 {src => kubi/src}/rendering/world.rs | 0 {src => kubi/src}/settings.rs | 0 {src => kubi/src}/transform.rs | 0 {src => kubi/src}/world.rs | 0 {src => kubi/src}/world/block.rs | 0 {src => kubi/src}/world/chunk.rs | 0 {src => kubi/src}/world/loading.rs | 0 {src => kubi/src}/world/mesh.rs | 0 {src => kubi/src}/world/mesh/data.rs | 0 {src => kubi/src}/world/neighbors.rs | 0 {src => kubi/src}/world/raycast.rs | 0 {src => kubi/src}/world/tasks.rs | 0 {src => kubi/src}/world/worldgen.rs | 0 60 files changed, 71 insertions(+), 36 deletions(-) delete mode 100644 crabs.txt create mode 100644 kubi-server/Cargo.toml create mode 100644 kubi-server/src/main.rs create mode 100644 kubi-shared/Cargo.toml create mode 100644 kubi-shared/src/lib.rs create mode 100644 kubi/Cargo.toml rename README.md => kubi/README.md (100%) rename {assets => kubi/assets}/blocks/bedrock.png (100%) rename {assets => kubi/assets}/blocks/dirt.png (100%) rename {assets => kubi/assets}/blocks/grass_side.png (100%) rename {assets => kubi/assets}/blocks/grass_side_snow.png (100%) rename {assets => kubi/assets}/blocks/grass_top.png (100%) rename {assets => kubi/assets}/blocks/leaf.png (100%) rename {assets => kubi/assets}/blocks/sand.png (100%) rename {assets => kubi/assets}/blocks/snow.png (100%) rename {assets => kubi/assets}/blocks/stone.png (100%) rename {assets => kubi/assets}/blocks/tall_grass.png (100%) rename {assets => kubi/assets}/blocks/torch.png (100%) rename {assets => kubi/assets}/blocks/wood.png (100%) rename {assets => kubi/assets}/blocks/wood_top.png (100%) rename {shaders => kubi/shaders}/colored.frag (100%) rename {shaders => kubi/shaders}/colored.vert (100%) rename {shaders => kubi/shaders}/selection_box.frag (100%) rename {shaders => kubi/shaders}/selection_box.vert (100%) rename {shaders => kubi/shaders}/world.frag (100%) rename {shaders => kubi/shaders}/world.vert (100%) rename {src => kubi/src}/block_placement.rs (100%) rename {src => kubi/src}/camera.rs (100%) rename {src => kubi/src}/camera/frustum.rs (100%) rename {src => kubi/src}/camera/matrices.rs (100%) rename {src => kubi/src}/control_flow.rs (100%) rename {src => kubi/src}/cursor_lock.rs (100%) rename {src => kubi/src}/delta_time.rs (100%) rename {src => kubi/src}/events.rs (100%) rename {src => kubi/src}/events/player_actions.rs (100%) rename {src => kubi/src}/fly_controller.rs (100%) rename {src => kubi/src}/input.rs (100%) rename {src => kubi/src}/logging.rs (100%) rename {src => kubi/src}/main.rs (100%) rename {src => kubi/src}/player.rs (100%) rename {src => kubi/src}/prefabs.rs (100%) rename {src => kubi/src}/prefabs/shaders.rs (100%) rename {src => kubi/src}/prefabs/texture.rs (100%) rename {src => kubi/src}/rendering.rs (100%) rename {src => kubi/src}/rendering/primitives.rs (100%) rename {src => kubi/src}/rendering/selection_box.rs (100%) rename {src => kubi/src}/rendering/world.rs (100%) rename {src => kubi/src}/settings.rs (100%) rename {src => kubi/src}/transform.rs (100%) rename {src => kubi/src}/world.rs (100%) rename {src => kubi/src}/world/block.rs (100%) rename {src => kubi/src}/world/chunk.rs (100%) rename {src => kubi/src}/world/loading.rs (100%) rename {src => kubi/src}/world/mesh.rs (100%) rename {src => kubi/src}/world/mesh/data.rs (100%) rename {src => kubi/src}/world/neighbors.rs (100%) rename {src => kubi/src}/world/raycast.rs (100%) rename {src => kubi/src}/world/tasks.rs (100%) rename {src => kubi/src}/world/worldgen.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index b558ff3..078f0ba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,35 +1,18 @@ -[package] -name = "kubi" -version = "0.1.0" -edition = "2021" - -[dependencies] -glium = "0.32" -image = { version = "0.24", default_features = false, features = ["png"] } -log = "0.4" -env_logger = "0.10" -strum = { version = "0.24", features = ["derive"] } -glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] } -hashbrown = "0.13" -rayon = "1.6" -shipyard = { version = "0.6", features = ["thread_local"] } -nohash-hasher = "0.2.0" -anyhow = "1.0" -flume = "0.10" -bracket-noise = "0.8" -#rkyv = "0.7" - -[profile.dev] -opt-level = 1 - -[profile.dev.package."*"] -opt-level = 1 - -[profile.dev.package.glium] -opt-level = 3 - -[profile.dev.package.bracket-noise] -opt-level = 3 - -[profile.dev.package.rayon] -opt-level = 3 +[workspace] +members = ["kubi", "kubi-server", "kubi-shared"] +resolver = "2" + +[profile.dev] +opt-level = 1 + +[profile.dev.package."*"] +opt-level = 1 + +[profile.dev.package.glium] +opt-level = 3 + +[profile.dev.package.bracket-noise] +opt-level = 3 + +[profile.dev.package.rayon] +opt-level = 3 diff --git a/crabs.txt b/crabs.txt deleted file mode 100644 index aecc062..0000000 --- a/crabs.txt +++ /dev/null @@ -1 +0,0 @@ -sorry no crabs here diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml new file mode 100644 index 0000000..abf3812 --- /dev/null +++ b/kubi-server/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "kubi-server" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/kubi-server/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml new file mode 100644 index 0000000..93a1ac2 --- /dev/null +++ b/kubi-shared/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "kubi-shared" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/kubi-shared/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml new file mode 100644 index 0000000..0a454a3 --- /dev/null +++ b/kubi/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "kubi" +version = "0.1.0" +edition = "2021" + +[dependencies] +glium = "0.32" +image = { version = "0.24", default_features = false, features = ["png"] } +log = "0.4" +env_logger = "0.10" +strum = { version = "0.24", features = ["derive"] } +glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] } +hashbrown = "0.13" +rayon = "1.6" +shipyard = { version = "0.6", features = ["thread_local"] } +nohash-hasher = "0.2.0" +anyhow = "1.0" +flume = "0.10" +bracket-noise = "0.8" +#rkyv = "0.7" diff --git a/README.md b/kubi/README.md similarity index 100% rename from README.md rename to kubi/README.md diff --git a/assets/blocks/bedrock.png b/kubi/assets/blocks/bedrock.png similarity index 100% rename from assets/blocks/bedrock.png rename to kubi/assets/blocks/bedrock.png diff --git a/assets/blocks/dirt.png b/kubi/assets/blocks/dirt.png similarity index 100% rename from assets/blocks/dirt.png rename to kubi/assets/blocks/dirt.png diff --git a/assets/blocks/grass_side.png b/kubi/assets/blocks/grass_side.png similarity index 100% rename from assets/blocks/grass_side.png rename to kubi/assets/blocks/grass_side.png diff --git a/assets/blocks/grass_side_snow.png b/kubi/assets/blocks/grass_side_snow.png similarity index 100% rename from assets/blocks/grass_side_snow.png rename to kubi/assets/blocks/grass_side_snow.png diff --git a/assets/blocks/grass_top.png b/kubi/assets/blocks/grass_top.png similarity index 100% rename from assets/blocks/grass_top.png rename to kubi/assets/blocks/grass_top.png diff --git a/assets/blocks/leaf.png b/kubi/assets/blocks/leaf.png similarity index 100% rename from assets/blocks/leaf.png rename to kubi/assets/blocks/leaf.png diff --git a/assets/blocks/sand.png b/kubi/assets/blocks/sand.png similarity index 100% rename from assets/blocks/sand.png rename to kubi/assets/blocks/sand.png diff --git a/assets/blocks/snow.png b/kubi/assets/blocks/snow.png similarity index 100% rename from assets/blocks/snow.png rename to kubi/assets/blocks/snow.png diff --git a/assets/blocks/stone.png b/kubi/assets/blocks/stone.png similarity index 100% rename from assets/blocks/stone.png rename to kubi/assets/blocks/stone.png diff --git a/assets/blocks/tall_grass.png b/kubi/assets/blocks/tall_grass.png similarity index 100% rename from assets/blocks/tall_grass.png rename to kubi/assets/blocks/tall_grass.png diff --git a/assets/blocks/torch.png b/kubi/assets/blocks/torch.png similarity index 100% rename from assets/blocks/torch.png rename to kubi/assets/blocks/torch.png diff --git a/assets/blocks/wood.png b/kubi/assets/blocks/wood.png similarity index 100% rename from assets/blocks/wood.png rename to kubi/assets/blocks/wood.png diff --git a/assets/blocks/wood_top.png b/kubi/assets/blocks/wood_top.png similarity index 100% rename from assets/blocks/wood_top.png rename to kubi/assets/blocks/wood_top.png diff --git a/shaders/colored.frag b/kubi/shaders/colored.frag similarity index 100% rename from shaders/colored.frag rename to kubi/shaders/colored.frag diff --git a/shaders/colored.vert b/kubi/shaders/colored.vert similarity index 100% rename from shaders/colored.vert rename to kubi/shaders/colored.vert diff --git a/shaders/selection_box.frag b/kubi/shaders/selection_box.frag similarity index 100% rename from shaders/selection_box.frag rename to kubi/shaders/selection_box.frag diff --git a/shaders/selection_box.vert b/kubi/shaders/selection_box.vert similarity index 100% rename from shaders/selection_box.vert rename to kubi/shaders/selection_box.vert diff --git a/shaders/world.frag b/kubi/shaders/world.frag similarity index 100% rename from shaders/world.frag rename to kubi/shaders/world.frag diff --git a/shaders/world.vert b/kubi/shaders/world.vert similarity index 100% rename from shaders/world.vert rename to kubi/shaders/world.vert diff --git a/src/block_placement.rs b/kubi/src/block_placement.rs similarity index 100% rename from src/block_placement.rs rename to kubi/src/block_placement.rs diff --git a/src/camera.rs b/kubi/src/camera.rs similarity index 100% rename from src/camera.rs rename to kubi/src/camera.rs diff --git a/src/camera/frustum.rs b/kubi/src/camera/frustum.rs similarity index 100% rename from src/camera/frustum.rs rename to kubi/src/camera/frustum.rs diff --git a/src/camera/matrices.rs b/kubi/src/camera/matrices.rs similarity index 100% rename from src/camera/matrices.rs rename to kubi/src/camera/matrices.rs diff --git a/src/control_flow.rs b/kubi/src/control_flow.rs similarity index 100% rename from src/control_flow.rs rename to kubi/src/control_flow.rs diff --git a/src/cursor_lock.rs b/kubi/src/cursor_lock.rs similarity index 100% rename from src/cursor_lock.rs rename to kubi/src/cursor_lock.rs diff --git a/src/delta_time.rs b/kubi/src/delta_time.rs similarity index 100% rename from src/delta_time.rs rename to kubi/src/delta_time.rs diff --git a/src/events.rs b/kubi/src/events.rs similarity index 100% rename from src/events.rs rename to kubi/src/events.rs diff --git a/src/events/player_actions.rs b/kubi/src/events/player_actions.rs similarity index 100% rename from src/events/player_actions.rs rename to kubi/src/events/player_actions.rs diff --git a/src/fly_controller.rs b/kubi/src/fly_controller.rs similarity index 100% rename from src/fly_controller.rs rename to kubi/src/fly_controller.rs diff --git a/src/input.rs b/kubi/src/input.rs similarity index 100% rename from src/input.rs rename to kubi/src/input.rs diff --git a/src/logging.rs b/kubi/src/logging.rs similarity index 100% rename from src/logging.rs rename to kubi/src/logging.rs diff --git a/src/main.rs b/kubi/src/main.rs similarity index 100% rename from src/main.rs rename to kubi/src/main.rs diff --git a/src/player.rs b/kubi/src/player.rs similarity index 100% rename from src/player.rs rename to kubi/src/player.rs diff --git a/src/prefabs.rs b/kubi/src/prefabs.rs similarity index 100% rename from src/prefabs.rs rename to kubi/src/prefabs.rs diff --git a/src/prefabs/shaders.rs b/kubi/src/prefabs/shaders.rs similarity index 100% rename from src/prefabs/shaders.rs rename to kubi/src/prefabs/shaders.rs diff --git a/src/prefabs/texture.rs b/kubi/src/prefabs/texture.rs similarity index 100% rename from src/prefabs/texture.rs rename to kubi/src/prefabs/texture.rs diff --git a/src/rendering.rs b/kubi/src/rendering.rs similarity index 100% rename from src/rendering.rs rename to kubi/src/rendering.rs diff --git a/src/rendering/primitives.rs b/kubi/src/rendering/primitives.rs similarity index 100% rename from src/rendering/primitives.rs rename to kubi/src/rendering/primitives.rs diff --git a/src/rendering/selection_box.rs b/kubi/src/rendering/selection_box.rs similarity index 100% rename from src/rendering/selection_box.rs rename to kubi/src/rendering/selection_box.rs diff --git a/src/rendering/world.rs b/kubi/src/rendering/world.rs similarity index 100% rename from src/rendering/world.rs rename to kubi/src/rendering/world.rs diff --git a/src/settings.rs b/kubi/src/settings.rs similarity index 100% rename from src/settings.rs rename to kubi/src/settings.rs diff --git a/src/transform.rs b/kubi/src/transform.rs similarity index 100% rename from src/transform.rs rename to kubi/src/transform.rs diff --git a/src/world.rs b/kubi/src/world.rs similarity index 100% rename from src/world.rs rename to kubi/src/world.rs diff --git a/src/world/block.rs b/kubi/src/world/block.rs similarity index 100% rename from src/world/block.rs rename to kubi/src/world/block.rs diff --git a/src/world/chunk.rs b/kubi/src/world/chunk.rs similarity index 100% rename from src/world/chunk.rs rename to kubi/src/world/chunk.rs diff --git a/src/world/loading.rs b/kubi/src/world/loading.rs similarity index 100% rename from src/world/loading.rs rename to kubi/src/world/loading.rs diff --git a/src/world/mesh.rs b/kubi/src/world/mesh.rs similarity index 100% rename from src/world/mesh.rs rename to kubi/src/world/mesh.rs diff --git a/src/world/mesh/data.rs b/kubi/src/world/mesh/data.rs similarity index 100% rename from src/world/mesh/data.rs rename to kubi/src/world/mesh/data.rs diff --git a/src/world/neighbors.rs b/kubi/src/world/neighbors.rs similarity index 100% rename from src/world/neighbors.rs rename to kubi/src/world/neighbors.rs diff --git a/src/world/raycast.rs b/kubi/src/world/raycast.rs similarity index 100% rename from src/world/raycast.rs rename to kubi/src/world/raycast.rs diff --git a/src/world/tasks.rs b/kubi/src/world/tasks.rs similarity index 100% rename from src/world/tasks.rs rename to kubi/src/world/tasks.rs diff --git a/src/world/worldgen.rs b/kubi/src/world/worldgen.rs similarity index 100% rename from src/world/worldgen.rs rename to kubi/src/world/worldgen.rs From c2b446ac7b05f321b43744c63a41c28e879ea6f7 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 01:50:14 +0100 Subject: [PATCH 003/160] move assets folder --- {kubi/assets => assets}/blocks/bedrock.png | Bin {kubi/assets => assets}/blocks/dirt.png | Bin {kubi/assets => assets}/blocks/grass_side.png | Bin {kubi/assets => assets}/blocks/grass_side_snow.png | Bin {kubi/assets => assets}/blocks/grass_top.png | Bin {kubi/assets => assets}/blocks/leaf.png | Bin {kubi/assets => assets}/blocks/sand.png | Bin {kubi/assets => assets}/blocks/snow.png | Bin {kubi/assets => assets}/blocks/stone.png | Bin {kubi/assets => assets}/blocks/tall_grass.png | Bin {kubi/assets => assets}/blocks/torch.png | Bin {kubi/assets => assets}/blocks/wood.png | Bin {kubi/assets => assets}/blocks/wood_top.png | Bin 13 files changed, 0 insertions(+), 0 deletions(-) rename {kubi/assets => assets}/blocks/bedrock.png (100%) rename {kubi/assets => assets}/blocks/dirt.png (100%) rename {kubi/assets => assets}/blocks/grass_side.png (100%) rename {kubi/assets => assets}/blocks/grass_side_snow.png (100%) rename {kubi/assets => assets}/blocks/grass_top.png (100%) rename {kubi/assets => assets}/blocks/leaf.png (100%) rename {kubi/assets => assets}/blocks/sand.png (100%) rename {kubi/assets => assets}/blocks/snow.png (100%) rename {kubi/assets => assets}/blocks/stone.png (100%) rename {kubi/assets => assets}/blocks/tall_grass.png (100%) rename {kubi/assets => assets}/blocks/torch.png (100%) rename {kubi/assets => assets}/blocks/wood.png (100%) rename {kubi/assets => assets}/blocks/wood_top.png (100%) diff --git a/kubi/assets/blocks/bedrock.png b/assets/blocks/bedrock.png similarity index 100% rename from kubi/assets/blocks/bedrock.png rename to assets/blocks/bedrock.png diff --git a/kubi/assets/blocks/dirt.png b/assets/blocks/dirt.png similarity index 100% rename from kubi/assets/blocks/dirt.png rename to assets/blocks/dirt.png diff --git a/kubi/assets/blocks/grass_side.png b/assets/blocks/grass_side.png similarity index 100% rename from kubi/assets/blocks/grass_side.png rename to assets/blocks/grass_side.png diff --git a/kubi/assets/blocks/grass_side_snow.png b/assets/blocks/grass_side_snow.png similarity index 100% rename from kubi/assets/blocks/grass_side_snow.png rename to assets/blocks/grass_side_snow.png diff --git a/kubi/assets/blocks/grass_top.png b/assets/blocks/grass_top.png similarity index 100% rename from kubi/assets/blocks/grass_top.png rename to assets/blocks/grass_top.png diff --git a/kubi/assets/blocks/leaf.png b/assets/blocks/leaf.png similarity index 100% rename from kubi/assets/blocks/leaf.png rename to assets/blocks/leaf.png diff --git a/kubi/assets/blocks/sand.png b/assets/blocks/sand.png similarity index 100% rename from kubi/assets/blocks/sand.png rename to assets/blocks/sand.png diff --git a/kubi/assets/blocks/snow.png b/assets/blocks/snow.png similarity index 100% rename from kubi/assets/blocks/snow.png rename to assets/blocks/snow.png diff --git a/kubi/assets/blocks/stone.png b/assets/blocks/stone.png similarity index 100% rename from kubi/assets/blocks/stone.png rename to assets/blocks/stone.png diff --git a/kubi/assets/blocks/tall_grass.png b/assets/blocks/tall_grass.png similarity index 100% rename from kubi/assets/blocks/tall_grass.png rename to assets/blocks/tall_grass.png diff --git a/kubi/assets/blocks/torch.png b/assets/blocks/torch.png similarity index 100% rename from kubi/assets/blocks/torch.png rename to assets/blocks/torch.png diff --git a/kubi/assets/blocks/wood.png b/assets/blocks/wood.png similarity index 100% rename from kubi/assets/blocks/wood.png rename to assets/blocks/wood.png diff --git a/kubi/assets/blocks/wood_top.png b/assets/blocks/wood_top.png similarity index 100% rename from kubi/assets/blocks/wood_top.png rename to assets/blocks/wood_top.png From 59b91bc23daa5c1322ec471f207b4213756bd9d9 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 02:37:11 +0100 Subject: [PATCH 004/160] add kubi-shared as dep --- kubi-server/Cargo.toml | 3 +-- kubi/Cargo.toml | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index abf3812..efed5a4 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -3,6 +3,5 @@ name = "kubi-server" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +kubi-shared = { path = "../kubi-shared" } diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 0a454a3..ef8189e 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] +kubi-shared = { path = "../kubi-shared" } glium = "0.32" image = { version = "0.24", default_features = false, features = ["png"] } log = "0.4" From db6c50ad8da83cc48365fac9afd769ad0a7a27c4 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 02:45:35 +0100 Subject: [PATCH 005/160] separate blocks into common --- kubi-server/src/main.rs | 2 +- kubi-shared/Cargo.toml | 1 + kubi-shared/src/blocks.rs | 11 +++++++++++ kubi-shared/src/lib.rs | 15 +-------------- kubi/src/world/block.rs | 15 +++++---------- kubi/src/world/mesh.rs | 2 +- kubi/src/world/raycast.rs | 3 +-- 7 files changed, 21 insertions(+), 28 deletions(-) create mode 100644 kubi-shared/src/blocks.rs diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index e7a11a9..d091d78 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -1,3 +1,3 @@ fn main() { - println!("Hello, world!"); + } diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 93a1ac2..d7a5ff3 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +strum = { version = "0.24", features = ["derive"] } diff --git a/kubi-shared/src/blocks.rs b/kubi-shared/src/blocks.rs new file mode 100644 index 0000000..ced61a8 --- /dev/null +++ b/kubi-shared/src/blocks.rs @@ -0,0 +1,11 @@ +use strum::EnumIter; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter)] +#[repr(u8)] +pub enum Block { + Air, + Stone, + Dirt, + Grass, + Sand, +} diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs index 7d12d9a..049a8aa 100644 --- a/kubi-shared/src/lib.rs +++ b/kubi-shared/src/lib.rs @@ -1,14 +1 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +pub mod blocks; diff --git a/kubi/src/world/block.rs b/kubi/src/world/block.rs index 92fba77..1ece14c 100644 --- a/kubi/src/world/block.rs +++ b/kubi/src/world/block.rs @@ -1,17 +1,12 @@ use strum::EnumIter; use crate::prefabs::BlockTexture; +pub use kubi_shared::blocks::Block; -#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter)] -#[repr(u8)] -pub enum Block { - Air, - Stone, - Dirt, - Grass, - Sand, +pub trait BlockDescriptorSource { + fn descriptor(self) -> BlockDescriptor; } -impl Block { - pub const fn descriptor(self) -> BlockDescriptor { +impl BlockDescriptorSource for Block { + fn descriptor(self) -> BlockDescriptor { match self { Self::Air => BlockDescriptor { name: "air", diff --git a/kubi/src/world/mesh.rs b/kubi/src/world/mesh.rs index f991594..608fc60 100644 --- a/kubi/src/world/mesh.rs +++ b/kubi/src/world/mesh.rs @@ -1,7 +1,7 @@ use strum::{EnumIter, IntoEnumIterator}; use glam::{Vec3A, vec3a, IVec3, ivec3}; use std::mem::discriminant; -use super::{chunk::CHUNK_SIZE, block::{Block, RenderType}}; +use super::{chunk::CHUNK_SIZE, block::{Block, RenderType, BlockDescriptorSource}}; use crate::rendering::world::ChunkVertex; pub mod data; diff --git a/kubi/src/world/raycast.rs b/kubi/src/world/raycast.rs index 733a197..1485abd 100644 --- a/kubi/src/world/raycast.rs +++ b/kubi/src/world/raycast.rs @@ -1,7 +1,6 @@ use glam::{Vec3, IVec3}; use shipyard::{View, Component, ViewMut, IntoIter, UniqueView}; -use crate::transform::Transform; - +use crate::{transform::Transform, world::block::BlockDescriptorSource}; use super::{ChunkStorage, block::Block}; const RAYCAST_STEP: f32 = 0.25; From 5b93fa763946bfb3fcbebc5a7ebb2f5956c62a58 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 03:23:39 +0100 Subject: [PATCH 006/160] move more things --- kubi-shared/Cargo.toml | 2 ++ kubi-shared/src/chunk.rs | 4 ++++ kubi-shared/src/lib.rs | 3 +++ kubi-shared/src/networking.rs | 2 ++ kubi-shared/src/networking/client.rs | 0 kubi-shared/src/networking/server.rs | 0 {kubi/src/world => kubi-shared/src}/worldgen.rs | 4 ++-- kubi/Cargo.toml | 3 +-- kubi/src/world.rs | 3 ++- kubi/src/world/chunk.rs | 5 +---- 10 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 kubi-shared/src/chunk.rs create mode 100644 kubi-shared/src/networking.rs create mode 100644 kubi-shared/src/networking/client.rs create mode 100644 kubi-shared/src/networking/server.rs rename {kubi/src/world => kubi-shared/src}/worldgen.rs (98%) diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index d7a5ff3..565c545 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -6,4 +6,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] } strum = { version = "0.24", features = ["derive"] } +bracket-noise = "0.8" diff --git a/kubi-shared/src/chunk.rs b/kubi-shared/src/chunk.rs new file mode 100644 index 0000000..de1b357 --- /dev/null +++ b/kubi-shared/src/chunk.rs @@ -0,0 +1,4 @@ +use crate::blocks::Block; + +pub const CHUNK_SIZE: usize = 32; +pub type BlockData = Box<[[[Block; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>; diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs index 049a8aa..dd0e7a5 100644 --- a/kubi-shared/src/lib.rs +++ b/kubi-shared/src/lib.rs @@ -1 +1,4 @@ pub mod blocks; +pub mod networking; +pub mod worldgen; +pub mod chunk; diff --git a/kubi-shared/src/networking.rs b/kubi-shared/src/networking.rs new file mode 100644 index 0000000..c07f47e --- /dev/null +++ b/kubi-shared/src/networking.rs @@ -0,0 +1,2 @@ +pub mod client; +pub mod server; diff --git a/kubi-shared/src/networking/client.rs b/kubi-shared/src/networking/client.rs new file mode 100644 index 0000000..e69de29 diff --git a/kubi-shared/src/networking/server.rs b/kubi-shared/src/networking/server.rs new file mode 100644 index 0000000..e69de29 diff --git a/kubi/src/world/worldgen.rs b/kubi-shared/src/worldgen.rs similarity index 98% rename from kubi/src/world/worldgen.rs rename to kubi-shared/src/worldgen.rs index 471055c..7e84845 100644 --- a/kubi/src/world/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -1,8 +1,8 @@ use glam::{IVec3, ivec3}; use bracket_noise::prelude::*; -use super::{ +use crate::{ chunk::{BlockData, CHUNK_SIZE}, - block::Block + blocks::Block }; pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index ef8189e..6978a12 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -6,16 +6,15 @@ edition = "2021" [dependencies] kubi-shared = { path = "../kubi-shared" } glium = "0.32" +glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] } image = { version = "0.24", default_features = false, features = ["png"] } log = "0.4" env_logger = "0.10" strum = { version = "0.24", features = ["derive"] } -glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] } hashbrown = "0.13" rayon = "1.6" shipyard = { version = "0.6", features = ["thread_local"] } nohash-hasher = "0.2.0" anyhow = "1.0" flume = "0.10" -bracket-noise = "0.8" #rkyv = "0.7" diff --git a/kubi/src/world.rs b/kubi/src/world.rs index 2e5bdf2..518fee7 100644 --- a/kubi/src/world.rs +++ b/kubi/src/world.rs @@ -4,13 +4,14 @@ use glam::IVec3; use hashbrown::HashMap; use anyhow::{Result, Context}; +pub use kubi_shared::worldgen; + pub mod chunk; pub mod block; pub mod tasks; pub mod loading; pub mod mesh; pub mod neighbors; -pub mod worldgen; pub mod raycast; use chunk::{Chunk, ChunkMesh}; diff --git a/kubi/src/world/chunk.rs b/kubi/src/world/chunk.rs index 672d767..285ab44 100644 --- a/kubi/src/world/chunk.rs +++ b/kubi/src/world/chunk.rs @@ -1,11 +1,8 @@ use glam::IVec3; use glium::{VertexBuffer, IndexBuffer}; -use super::block::Block; use crate::rendering::world::ChunkVertex; -pub const CHUNK_SIZE: usize = 32; - -pub type BlockData = Box<[[[Block; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>; +pub use kubi_shared::chunk::{CHUNK_SIZE, BlockData}; pub struct ChunkData { pub blocks: BlockData, From f294e0e159821585528cde991360403d9f7b9f59 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 03:42:58 +0100 Subject: [PATCH 007/160] use rkyv --- kubi-shared/Cargo.toml | 3 ++- kubi-shared/src/networking.rs | 1 + kubi-shared/src/networking/messages.rs | 11 +++++++++++ kubi/Cargo.toml | 1 - 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 kubi-shared/src/networking/messages.rs diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 565c545..ff834cc 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] } +glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math", "rkyv"] } strum = { version = "0.24", features = ["derive"] } bracket-noise = "0.8" +rkyv = { version = "0.7", features = ["validation", "archive_le"] } diff --git a/kubi-shared/src/networking.rs b/kubi-shared/src/networking.rs index c07f47e..527f935 100644 --- a/kubi-shared/src/networking.rs +++ b/kubi-shared/src/networking.rs @@ -1,2 +1,3 @@ pub mod client; pub mod server; +pub mod messages; diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs new file mode 100644 index 0000000..ba01e36 --- /dev/null +++ b/kubi-shared/src/networking/messages.rs @@ -0,0 +1,11 @@ +use rkyv::{Archive, Deserialize, Serialize}; + +#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] +pub enum ClientToServerMessage { + Placeholder +} + +#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] +pub enum ServerToClientMessage { + Placeholder +} diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 6978a12..105d785 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -17,4 +17,3 @@ shipyard = { version = "0.6", features = ["thread_local"] } nohash-hasher = "0.2.0" anyhow = "1.0" flume = "0.10" -#rkyv = "0.7" From acbb159606dd7bfc35ba8e90d13aa01f1e0f3bdd Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 04:14:53 +0100 Subject: [PATCH 008/160] WIP controller support --- kubi/Cargo.toml | 1 + kubi/src/input.rs | 80 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 69 insertions(+), 12 deletions(-) diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 105d785..5fdfaae 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -17,3 +17,4 @@ shipyard = { version = "0.6", features = ["thread_local"] } nohash-hasher = "0.2.0" anyhow = "1.0" flume = "0.10" +gilrs = "0.10" diff --git a/kubi/src/input.rs b/kubi/src/input.rs index 7f408e9..151b212 100644 --- a/kubi/src/input.rs +++ b/kubi/src/input.rs @@ -1,8 +1,9 @@ -use glam::{Vec2, DVec2}; +use gilrs::{Gilrs, GamepadId, Button, Event, Axis}; +use glam::{Vec2, DVec2, vec2}; use glium::glutin::event::{DeviceEvent, VirtualKeyCode, ElementState}; use hashbrown::HashSet; use nohash_hasher::BuildNoHashHasher; -use shipyard::{AllStoragesView, Unique, View, IntoIter, UniqueViewMut, Workload, IntoWorkload, UniqueView}; +use shipyard::{AllStoragesView, Unique, View, IntoIter, UniqueViewMut, Workload, IntoWorkload, UniqueView, NonSendSync}; use crate::events::InputDeviceEvent; #[derive(Unique, Clone, Copy, Default, Debug)] @@ -23,7 +24,16 @@ pub struct RawInputState { pub mouse_delta: DVec2 } -pub fn process_events( +#[derive(Unique)] +pub struct GilrsWrapper(Gilrs); + +#[derive(Unique, Default, Clone, Copy)] +pub struct ActiveGamepad(Option); + +//maybe we should manage gamepad state ourselves just like keyboard? +//at least for the sake of consitency + +fn process_events( device_events: View, mut input_state: UniqueViewMut, ) { @@ -51,26 +61,68 @@ pub fn process_events( } } -pub fn update_input_states ( - raw_inputs: UniqueView, +fn process_gilrs_events( + mut gilrs: NonSendSync>, + mut active_gamepad: UniqueViewMut +) { + while let Some(Event { id, event: _, time: _ }) = gilrs.0.next_event() { + active_gamepad.0 = Some(id); + } +} + +fn input_start( mut inputs: UniqueViewMut, mut prev_inputs: UniqueViewMut, ) { prev_inputs.0 = *inputs; - inputs.movement = Vec2::new( + *inputs = Inputs::default(); +} + +fn update_input_state ( + raw_inputs: UniqueView, + mut inputs: UniqueViewMut, +) { + inputs.movement += Vec2::new( raw_inputs.keyboard_state.contains(&VirtualKeyCode::D) as u32 as f32 - raw_inputs.keyboard_state.contains(&VirtualKeyCode::A) as u32 as f32, raw_inputs.keyboard_state.contains(&VirtualKeyCode::W) as u32 as f32 - raw_inputs.keyboard_state.contains(&VirtualKeyCode::S) as u32 as f32 - ).normalize_or_zero(); - inputs.look = raw_inputs.mouse_delta.as_vec2(); - inputs.action_a = raw_inputs.button_state[1]; - inputs.action_b = raw_inputs.button_state[3]; + ); + inputs.look += raw_inputs.mouse_delta.as_vec2(); + inputs.action_a |= raw_inputs.button_state[1]; + inputs.action_b |= raw_inputs.button_state[3]; +} + +fn update_input_state_gamepad ( + gilrs: NonSendSync>, + active_gamepad: UniqueView, + mut inputs: UniqueViewMut, +) { + if let Some(Some(gamepad)) = active_gamepad.0.map(|id| gilrs.0.connected_gamepad(id)) { + let lx = gamepad.axis_data(Axis::LeftStickX).map(|x| x.value()).unwrap_or_default(); + let ly = gamepad.axis_data(Axis::LeftStickY).map(|y| y.value()).unwrap_or_default(); + let rx = gamepad.axis_data(Axis::RightStickX).map(|x| x.value()).unwrap_or_default(); + let ry = gamepad.axis_data(Axis::RightStickY).map(|y| y.value()).unwrap_or_default(); + let left_stick = vec2(lx, ly); + let right_stick = vec2(rx, ry); + inputs.movement += left_stick; + inputs.look += right_stick; + inputs.action_a |= gamepad.is_pressed(Button::South); + inputs.action_b |= gamepad.is_pressed(Button::East); + } +} + +fn input_end( + mut inputs: UniqueViewMut, +) { + inputs.movement = inputs.movement.normalize_or_zero(); } pub fn init_input ( storages: AllStoragesView ) { + storages.add_unique_non_send_sync(GilrsWrapper(Gilrs::new().expect("Failed to initialize Gilrs"))); + storages.add_unique(ActiveGamepad::default()); storages.add_unique(Inputs::default()); storages.add_unique(PrevInputs::default()); storages.add_unique(RawInputState::default()); @@ -78,7 +130,11 @@ pub fn init_input ( pub fn process_inputs() -> Workload { ( - process_events, - update_input_states + process_events, + process_gilrs_events, + input_start, + update_input_state, + update_input_state_gamepad, + input_end, ).into_workload() } From 3af40c28b8ee4c9659d14f43fcd3e6afe0705d91 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 04:18:29 +0100 Subject: [PATCH 009/160] fix stick input --- kubi/src/input.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/kubi/src/input.rs b/kubi/src/input.rs index 151b212..902dbda 100644 --- a/kubi/src/input.rs +++ b/kubi/src/input.rs @@ -99,12 +99,8 @@ fn update_input_state_gamepad ( mut inputs: UniqueViewMut, ) { if let Some(Some(gamepad)) = active_gamepad.0.map(|id| gilrs.0.connected_gamepad(id)) { - let lx = gamepad.axis_data(Axis::LeftStickX).map(|x| x.value()).unwrap_or_default(); - let ly = gamepad.axis_data(Axis::LeftStickY).map(|y| y.value()).unwrap_or_default(); - let rx = gamepad.axis_data(Axis::RightStickX).map(|x| x.value()).unwrap_or_default(); - let ry = gamepad.axis_data(Axis::RightStickY).map(|y| y.value()).unwrap_or_default(); - let left_stick = vec2(lx, ly); - let right_stick = vec2(rx, ry); + let left_stick = vec2(gamepad.value(Axis::LeftStickX), gamepad.value(Axis::LeftStickY)); + let right_stick = vec2(gamepad.value(Axis::RightStickX), gamepad.value(Axis::RightStickY)); inputs.movement += left_stick; inputs.look += right_stick; inputs.action_a |= gamepad.is_pressed(Button::South); From 56d85252b0deb67d1932c3e9ce90e081535d9b8e Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 04:20:13 +0100 Subject: [PATCH 010/160] use xinput, invert y --- kubi/Cargo.toml | 2 +- kubi/src/input.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 5fdfaae..564478e 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -17,4 +17,4 @@ shipyard = { version = "0.6", features = ["thread_local"] } nohash-hasher = "0.2.0" anyhow = "1.0" flume = "0.10" -gilrs = "0.10" +gilrs = { version = "0.10", default_features = false, features = ["xinput"] } diff --git a/kubi/src/input.rs b/kubi/src/input.rs index 902dbda..3957d38 100644 --- a/kubi/src/input.rs +++ b/kubi/src/input.rs @@ -100,7 +100,7 @@ fn update_input_state_gamepad ( ) { if let Some(Some(gamepad)) = active_gamepad.0.map(|id| gilrs.0.connected_gamepad(id)) { let left_stick = vec2(gamepad.value(Axis::LeftStickX), gamepad.value(Axis::LeftStickY)); - let right_stick = vec2(gamepad.value(Axis::RightStickX), gamepad.value(Axis::RightStickY)); + let right_stick = vec2(gamepad.value(Axis::RightStickX), -gamepad.value(Axis::RightStickY)); inputs.movement += left_stick; inputs.look += right_stick; inputs.action_a |= gamepad.is_pressed(Button::South); From 1f8c6ea223e404d1ce0c71c205112ab7ce1e5eed Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 04:23:28 +0100 Subject: [PATCH 011/160] maybe this will work? --- kubi/src/input.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi/src/input.rs b/kubi/src/input.rs index 3957d38..3e763de 100644 --- a/kubi/src/input.rs +++ b/kubi/src/input.rs @@ -98,7 +98,7 @@ fn update_input_state_gamepad ( active_gamepad: UniqueView, mut inputs: UniqueViewMut, ) { - if let Some(Some(gamepad)) = active_gamepad.0.map(|id| gilrs.0.connected_gamepad(id)) { + if let Some(gamepad) = active_gamepad.0.map(|id| gilrs.0.gamepad(id)) { let left_stick = vec2(gamepad.value(Axis::LeftStickX), gamepad.value(Axis::LeftStickY)); let right_stick = vec2(gamepad.value(Axis::RightStickX), -gamepad.value(Axis::RightStickY)); inputs.movement += left_stick; From ab7c18134590fcef10d9023ebd0d13f70abf0eda Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 04:32:33 +0100 Subject: [PATCH 012/160] fix excessive logging --- kubi/src/logging.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi/src/logging.rs b/kubi/src/logging.rs index 013b4e9..c3b8be7 100644 --- a/kubi/src/logging.rs +++ b/kubi/src/logging.rs @@ -7,7 +7,7 @@ use std::io::Write; pub fn init() { let mut env = Env::default(); if cfg!(debug_assertions) { - env = env.filter_or("RUST_LOG", "trace"); + env = env.filter_or("RUST_LOG", "trace,gilrs=warn,rusty_xinput=warn"); } Builder::from_env(env) .format(|buf, record| { From b0642028d1f5d3e6407f31ce6bb0b10417801c45 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 30 Jan 2023 20:23:00 +0100 Subject: [PATCH 013/160] CheckBytes --- kubi-shared/Cargo.toml | 1 + kubi-shared/src/networking/messages.rs | 3 +++ kubi/src/world/block.rs | 1 - 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index ff834cc..73c42a5 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -10,3 +10,4 @@ glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math", strum = { version = "0.24", features = ["derive"] } bracket-noise = "0.8" rkyv = { version = "0.7", features = ["validation", "archive_le"] } +bytecheck = "*" diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index ba01e36..b0734e5 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -1,11 +1,14 @@ use rkyv::{Archive, Deserialize, Serialize}; +use bytecheck::CheckBytes; #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] +#[archive_attr(derive(CheckBytes, Debug))] pub enum ClientToServerMessage { Placeholder } #[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] +#[archive_attr(derive(CheckBytes, Debug))] pub enum ServerToClientMessage { Placeholder } diff --git a/kubi/src/world/block.rs b/kubi/src/world/block.rs index 1ece14c..45c2552 100644 --- a/kubi/src/world/block.rs +++ b/kubi/src/world/block.rs @@ -1,4 +1,3 @@ -use strum::EnumIter; use crate::prefabs::BlockTexture; pub use kubi_shared::blocks::Block; From 1f5b5853b24d6846ec6975b1b3aa23a6646ea3cd Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 31 Jan 2023 01:28:35 +0100 Subject: [PATCH 014/160] replace `rkyv` with `serde` and `bincode` change to serde --- kubi-shared/Cargo.toml | 6 +++--- kubi-shared/src/networking.rs | 2 -- kubi-shared/src/networking/client.rs | 0 kubi-shared/src/networking/messages.rs | 29 +++++++++++++++++++------- kubi-shared/src/networking/server.rs | 0 kubi/Cargo.toml | 2 +- 6 files changed, 25 insertions(+), 14 deletions(-) delete mode 100644 kubi-shared/src/networking/client.rs delete mode 100644 kubi-shared/src/networking/server.rs diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 73c42a5..6fa1d1a 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math", "rkyv"] } +glam = { version = "0.22", features = ["debug-glam-assert", "fast-math", "serde"] } strum = { version = "0.24", features = ["derive"] } +bincode = { version = "2.0.0-rc", default_features = false, features = ["std", "serde"] } +serde = { version = "1.0", features = ["derive"] } bracket-noise = "0.8" -rkyv = { version = "0.7", features = ["validation", "archive_le"] } -bytecheck = "*" diff --git a/kubi-shared/src/networking.rs b/kubi-shared/src/networking.rs index 527f935..ba63992 100644 --- a/kubi-shared/src/networking.rs +++ b/kubi-shared/src/networking.rs @@ -1,3 +1 @@ -pub mod client; -pub mod server; pub mod messages; diff --git a/kubi-shared/src/networking/client.rs b/kubi-shared/src/networking/client.rs deleted file mode 100644 index e69de29..0000000 diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index b0734e5..af646e7 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -1,14 +1,27 @@ -use rkyv::{Archive, Deserialize, Serialize}; -use bytecheck::CheckBytes; +use glam::{Vec3, Quat}; +use serde::{Serialize, Deserialize}; -#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] -#[archive_attr(derive(CheckBytes, Debug))] +#[derive(Serialize, Deserialize)] pub enum ClientToServerMessage { - Placeholder + ClientHello { + username: String, + password: Option, + }, + PositionChanged { + position: Vec3, + direction: Quat + } } -#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)] -#[archive_attr(derive(CheckBytes, Debug))] +#[derive(Serialize, Deserialize)] pub enum ServerToClientMessage { - Placeholder + ServerHello { + client_id: u16, + }, + ServerFuckOff { + reason: String, + }, + PlayerPositionChanged { + + }, } diff --git a/kubi-shared/src/networking/server.rs b/kubi-shared/src/networking/server.rs deleted file mode 100644 index e69de29..0000000 diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 564478e..099fa92 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] kubi-shared = { path = "../kubi-shared" } glium = "0.32" -glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] } +glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } image = { version = "0.24", default_features = false, features = ["png"] } log = "0.4" env_logger = "0.10" From 6f45a0ee778c9ed40f9da509c27fb14a5f8cbc8c Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 31 Jan 2023 02:23:44 +0100 Subject: [PATCH 015/160] upd --- kubi-shared/Cargo.toml | 1 + kubi-shared/src/networking/messages.rs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 6fa1d1a..6568ab7 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -11,3 +11,4 @@ strum = { version = "0.24", features = ["derive"] } bincode = { version = "2.0.0-rc", default_features = false, features = ["std", "serde"] } serde = { version = "1.0", features = ["derive"] } bracket-noise = "0.8" +#laminar = "0.5.0" diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index af646e7..5940f24 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -8,6 +8,8 @@ pub enum ClientToServerMessage { password: Option, }, PositionChanged { + client_id: u8, + secret: u32, position: Vec3, direction: Quat } @@ -16,7 +18,8 @@ pub enum ClientToServerMessage { #[derive(Serialize, Deserialize)] pub enum ServerToClientMessage { ServerHello { - client_id: u16, + client_id: u8, + secret: u32, }, ServerFuckOff { reason: String, From 5c3062d13f863aa300db6fd73af37ef67da47437 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 31 Jan 2023 02:51:54 +0100 Subject: [PATCH 016/160] c --- kubi-shared/Cargo.toml | 1 + kubi-shared/src/networking.rs | 2 ++ kubi-shared/src/networking/client.rs | 23 +++++++++++++++++++++++ kubi-shared/src/networking/server.rs | 0 4 files changed, 26 insertions(+) create mode 100644 kubi-shared/src/networking/client.rs create mode 100644 kubi-shared/src/networking/server.rs diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 6568ab7..0cae1ee 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -10,5 +10,6 @@ glam = { version = "0.22", features = ["debug-glam-assert", "fast-math", "serde" strum = { version = "0.24", features = ["derive"] } bincode = { version = "2.0.0-rc", default_features = false, features = ["std", "serde"] } serde = { version = "1.0", features = ["derive"] } +anyhow = "1.0" bracket-noise = "0.8" #laminar = "0.5.0" diff --git a/kubi-shared/src/networking.rs b/kubi-shared/src/networking.rs index ba63992..8a4e7ed 100644 --- a/kubi-shared/src/networking.rs +++ b/kubi-shared/src/networking.rs @@ -1 +1,3 @@ pub mod messages; +pub mod client; +pub mod server; diff --git a/kubi-shared/src/networking/client.rs b/kubi-shared/src/networking/client.rs new file mode 100644 index 0000000..d112490 --- /dev/null +++ b/kubi-shared/src/networking/client.rs @@ -0,0 +1,23 @@ +use std::net::{UdpSocket, SocketAddr}; +use super::messages::ClientToServerMessage; + +const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() + .with_little_endian() + .with_variable_int_encoding() + .skip_fixed_array_length(); + +pub struct Client { + socket: UdpSocket +} +impl Client { + pub fn bind(addr: SocketAddr) -> anyhow::Result { + Ok(Self { + socket: UdpSocket::bind(addr)? + }) + } + pub fn send(&self, message: ClientToServerMessage) -> anyhow::Result<()> { + let bytes = bincode::serde::encode_to_vec(message, BINCODE_CONFIG)?; + self.socket.send(&bytes)?; + Ok(()) + } +} diff --git a/kubi-shared/src/networking/server.rs b/kubi-shared/src/networking/server.rs new file mode 100644 index 0000000..e69de29 From 1c0409a9cf6e34139af0bfb9aebec4118fe10a71 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 31 Jan 2023 03:06:30 +0100 Subject: [PATCH 017/160] use bincode derive instead of serde due to potential issues --- kubi-shared/Cargo.toml | 3 +-- kubi-shared/src/blocks.rs | 3 ++- kubi-shared/src/networking/client.rs | 2 +- kubi-shared/src/networking/messages.rs | 31 +++++++++++++++++++------- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 0cae1ee..d3d65bb 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -8,8 +8,7 @@ edition = "2021" [dependencies] glam = { version = "0.22", features = ["debug-glam-assert", "fast-math", "serde"] } strum = { version = "0.24", features = ["derive"] } -bincode = { version = "2.0.0-rc", default_features = false, features = ["std", "serde"] } -serde = { version = "1.0", features = ["derive"] } +bincode = "2.0.0-rc" anyhow = "1.0" bracket-noise = "0.8" #laminar = "0.5.0" diff --git a/kubi-shared/src/blocks.rs b/kubi-shared/src/blocks.rs index ced61a8..3e601fc 100644 --- a/kubi-shared/src/blocks.rs +++ b/kubi-shared/src/blocks.rs @@ -1,6 +1,7 @@ +use bincode::{Encode, Decode}; use strum::EnumIter; -#[derive(Clone, Copy, Debug, PartialEq, Eq, EnumIter)] +#[derive(Encode, Decode, Clone, Copy, Debug, PartialEq, Eq, EnumIter)] #[repr(u8)] pub enum Block { Air, diff --git a/kubi-shared/src/networking/client.rs b/kubi-shared/src/networking/client.rs index d112490..863715f 100644 --- a/kubi-shared/src/networking/client.rs +++ b/kubi-shared/src/networking/client.rs @@ -16,7 +16,7 @@ impl Client { }) } pub fn send(&self, message: ClientToServerMessage) -> anyhow::Result<()> { - let bytes = bincode::serde::encode_to_vec(message, BINCODE_CONFIG)?; + let bytes = bincode::encode_to_vec(message, BINCODE_CONFIG)?; self.socket.send(&bytes)?; Ok(()) } diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index 5940f24..2e2609b 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -1,7 +1,11 @@ -use glam::{Vec3, Quat}; -use serde::{Serialize, Deserialize}; +use bincode::{Encode, Decode}; +use crate::chunk::BlockData; -#[derive(Serialize, Deserialize)] +type IVec3Arr = [i32; 3]; +type Vec3Arr = [f32; 3]; +type QuatArr = [f32; 3]; + +#[derive(Encode, Decode)] pub enum ClientToServerMessage { ClientHello { username: String, @@ -10,12 +14,17 @@ pub enum ClientToServerMessage { PositionChanged { client_id: u8, secret: u32, - position: Vec3, - direction: Quat - } + position: Vec3Arr, + direction: QuatArr, + }, + ChunkRequest { + client_id: u8, + secret: u32, + chunk: IVec3Arr, + }, } -#[derive(Serialize, Deserialize)] +#[derive(Encode, Decode)] pub enum ServerToClientMessage { ServerHello { client_id: u8, @@ -25,6 +34,12 @@ pub enum ServerToClientMessage { reason: String, }, PlayerPositionChanged { - + client_id: u8, + position: Vec3Arr, + direction: QuatArr, }, + ChunkResponse { + chunk: IVec3Arr, + data: BlockData + } } From a7a20093d62b17acfed9c91ea50b93e61e8c323f Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 31 Jan 2023 03:12:23 +0100 Subject: [PATCH 018/160] move config --- kubi-shared/src/lib.rs | 5 +++++ kubi-shared/src/networking/client.rs | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs index dd0e7a5..8fb7339 100644 --- a/kubi-shared/src/lib.rs +++ b/kubi-shared/src/lib.rs @@ -2,3 +2,8 @@ pub mod blocks; pub mod networking; pub mod worldgen; pub mod chunk; + +pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() + .with_little_endian() + .with_variable_int_encoding() + .skip_fixed_array_length(); diff --git a/kubi-shared/src/networking/client.rs b/kubi-shared/src/networking/client.rs index 863715f..82d0ddd 100644 --- a/kubi-shared/src/networking/client.rs +++ b/kubi-shared/src/networking/client.rs @@ -1,10 +1,7 @@ use std::net::{UdpSocket, SocketAddr}; use super::messages::ClientToServerMessage; -const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() - .with_little_endian() - .with_variable_int_encoding() - .skip_fixed_array_length(); +use crate::BINCODE_CONFIG; pub struct Client { socket: UdpSocket From 728c468a7066e3da95d967474c0c716788aa760b Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 1 Feb 2023 03:16:23 +0100 Subject: [PATCH 019/160] create net lib --- Cargo.toml | 2 +- kubi-shared/Cargo.toml | 1 - kubi-shared/src/lib.rs | 5 ---- kubi-shared/src/networking.rs | 2 -- kubi-shared/src/networking/client.rs | 20 ---------------- kubi-shared/src/networking/server.rs | 0 kubi-udp/Cargo.toml | 10 ++++++++ kubi-udp/src/client.rs | 36 ++++++++++++++++++++++++++++ kubi-udp/src/lib.rs | 11 +++++++++ kubi-udp/src/packet.rs | 10 ++++++++ kubi-udp/src/server.rs | 14 +++++++++++ 11 files changed, 82 insertions(+), 29 deletions(-) delete mode 100644 kubi-shared/src/networking/client.rs delete mode 100644 kubi-shared/src/networking/server.rs create mode 100644 kubi-udp/Cargo.toml create mode 100644 kubi-udp/src/client.rs create mode 100644 kubi-udp/src/lib.rs create mode 100644 kubi-udp/src/packet.rs create mode 100644 kubi-udp/src/server.rs diff --git a/Cargo.toml b/Cargo.toml index 078f0ba..c0cf813 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["kubi", "kubi-server", "kubi-shared"] +members = ["kubi", "kubi-server", "kubi-shared", "kubi-udp"] resolver = "2" [profile.dev] diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index d3d65bb..c42eb3b 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -11,4 +11,3 @@ strum = { version = "0.24", features = ["derive"] } bincode = "2.0.0-rc" anyhow = "1.0" bracket-noise = "0.8" -#laminar = "0.5.0" diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs index 8fb7339..dd0e7a5 100644 --- a/kubi-shared/src/lib.rs +++ b/kubi-shared/src/lib.rs @@ -2,8 +2,3 @@ pub mod blocks; pub mod networking; pub mod worldgen; pub mod chunk; - -pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() - .with_little_endian() - .with_variable_int_encoding() - .skip_fixed_array_length(); diff --git a/kubi-shared/src/networking.rs b/kubi-shared/src/networking.rs index 8a4e7ed..ba63992 100644 --- a/kubi-shared/src/networking.rs +++ b/kubi-shared/src/networking.rs @@ -1,3 +1 @@ pub mod messages; -pub mod client; -pub mod server; diff --git a/kubi-shared/src/networking/client.rs b/kubi-shared/src/networking/client.rs deleted file mode 100644 index 82d0ddd..0000000 --- a/kubi-shared/src/networking/client.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::net::{UdpSocket, SocketAddr}; -use super::messages::ClientToServerMessage; - -use crate::BINCODE_CONFIG; - -pub struct Client { - socket: UdpSocket -} -impl Client { - pub fn bind(addr: SocketAddr) -> anyhow::Result { - Ok(Self { - socket: UdpSocket::bind(addr)? - }) - } - pub fn send(&self, message: ClientToServerMessage) -> anyhow::Result<()> { - let bytes = bincode::encode_to_vec(message, BINCODE_CONFIG)?; - self.socket.send(&bytes)?; - Ok(()) - } -} diff --git a/kubi-shared/src/networking/server.rs b/kubi-shared/src/networking/server.rs deleted file mode 100644 index e69de29..0000000 diff --git a/kubi-udp/Cargo.toml b/kubi-udp/Cargo.toml new file mode 100644 index 0000000..8a64827 --- /dev/null +++ b/kubi-udp/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "kubi-udp" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bincode = "2.0.0-rc" +anyhow = "1.0" diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs new file mode 100644 index 0000000..e98a8b9 --- /dev/null +++ b/kubi-udp/src/client.rs @@ -0,0 +1,36 @@ +use std::{ + net::{UdpSocket, SocketAddr}, + marker::PhantomData +}; +use bincode::{Encode, Decode}; +use crate::{BINCODE_CONFIG, packet::ClientPacket}; + +pub struct Client where T: Encode + Decode { + socket: UdpSocket, + _marker: PhantomData +} +impl Client where T: Encode + Decode { + pub fn connect(addr: SocketAddr) -> anyhow::Result { + let bind_addr: SocketAddr = "127.0.0.1:0".parse().unwrap(); + let socket = UdpSocket::bind(bind_addr)?; + socket.set_nonblocking(true)?; + socket.connect(addr)?; + Ok(Self { + socket, + _marker: PhantomData + }) + } + fn send_packet(&self, packet: &ClientPacket) -> anyhow::Result<()> { + let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; + self.socket.send(&bytes)?; + Ok(()) + } + pub fn send(&self, message: T) -> anyhow::Result<()> { + self.send_packet(&ClientPacket::Data(message))?; + Ok(()) + } + pub fn disconnect(&self) -> anyhow::Result<()> { + self.send_packet(&ClientPacket::Disconnect)?; + Ok(()) + } +} diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs new file mode 100644 index 0000000..caf5110 --- /dev/null +++ b/kubi-udp/src/lib.rs @@ -0,0 +1,11 @@ +pub(crate) mod client; +pub(crate) mod server; +pub(crate) mod packet; + +pub use server::Server; +pub use client::Client; + +pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() + .with_little_endian() + .with_variable_int_encoding() + .skip_fixed_array_length(); diff --git a/kubi-udp/src/packet.rs b/kubi-udp/src/packet.rs new file mode 100644 index 0000000..49ca38d --- /dev/null +++ b/kubi-udp/src/packet.rs @@ -0,0 +1,10 @@ +use bincode::{Encode, Decode}; + +#[repr(u8)] +#[derive(Encode, Decode)] +pub enum ClientPacket where T: Encode + Decode { + Connect, + Disconnect, + Heartbeat, + Data(T) +} diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs new file mode 100644 index 0000000..9935fc3 --- /dev/null +++ b/kubi-udp/src/server.rs @@ -0,0 +1,14 @@ +use std::net::{UdpSocket, SocketAddr}; +use crate::BINCODE_CONFIG; + +pub struct Server { + socket: UdpSocket, +} +impl Server { + pub fn bind(addr: SocketAddr) -> anyhow::Result { + let socket = UdpSocket::bind(addr)?; + socket.set_nonblocking(true)?; + socket.set_broadcast(true)?; + Ok(Self { socket }) + } +} From e6ec24a55cd895c77f2f6b10d543b498089cecad Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 1 Feb 2023 03:24:06 +0100 Subject: [PATCH 020/160] client --- kubi-udp/src/client.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index e98a8b9..f2be789 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -5,31 +5,35 @@ use std::{ use bincode::{Encode, Decode}; use crate::{BINCODE_CONFIG, packet::ClientPacket}; -pub struct Client where T: Encode + Decode { +pub struct Client where S: Encode + Decode, R: Encode + Decode { socket: UdpSocket, - _marker: PhantomData + _s: PhantomData, + _r: PhantomData, } -impl Client where T: Encode + Decode { +impl Client where S: Encode + Decode, R: Encode + Decode { pub fn connect(addr: SocketAddr) -> anyhow::Result { let bind_addr: SocketAddr = "127.0.0.1:0".parse().unwrap(); let socket = UdpSocket::bind(bind_addr)?; socket.set_nonblocking(true)?; socket.connect(addr)?; - Ok(Self { + let client = Self { socket, - _marker: PhantomData - }) + _s: PhantomData, + _r: PhantomData, + }; + client.send_packet(&ClientPacket::Connect)?; + Ok(client) } - fn send_packet(&self, packet: &ClientPacket) -> anyhow::Result<()> { + fn send_packet(&self, packet: &ClientPacket) -> anyhow::Result<()> { let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; self.socket.send(&bytes)?; Ok(()) } - pub fn send(&self, message: T) -> anyhow::Result<()> { + pub fn send_message(&self, message: S) -> anyhow::Result<()> { self.send_packet(&ClientPacket::Data(message))?; Ok(()) } - pub fn disconnect(&self) -> anyhow::Result<()> { + pub fn disconnect(self) -> anyhow::Result<()> { self.send_packet(&ClientPacket::Disconnect)?; Ok(()) } From 65ecf0de62a0732dd8ff057ac7d9c17423882bf1 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 1 Feb 2023 03:25:12 +0100 Subject: [PATCH 021/160] no drop check is needed --- kubi-udp/src/client.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index f2be789..5f64b2c 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -7,8 +7,8 @@ use crate::{BINCODE_CONFIG, packet::ClientPacket}; pub struct Client where S: Encode + Decode, R: Encode + Decode { socket: UdpSocket, - _s: PhantomData, - _r: PhantomData, + _s: PhantomData<*const S>, + _r: PhantomData<*const R>, } impl Client where S: Encode + Decode, R: Encode + Decode { pub fn connect(addr: SocketAddr) -> anyhow::Result { From 8ff2a828adcb6de8eb790a5ac98519e4b2e0e4c4 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 1 Feb 2023 03:25:39 +0100 Subject: [PATCH 022/160] x --- kubi-udp/src/client.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 5f64b2c..320ba2d 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -24,6 +24,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { client.send_packet(&ClientPacket::Connect)?; Ok(client) } + //maybe move generics here if possible? fn send_packet(&self, packet: &ClientPacket) -> anyhow::Result<()> { let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; self.socket.send(&bytes)?; From 3593fcd4d5a6df27189a447b81ff2e964dbeec7a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 1 Feb 2023 23:34:27 +0100 Subject: [PATCH 023/160] fix panic --- kubi/src/camera/matrices.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi/src/camera/matrices.rs b/kubi/src/camera/matrices.rs index b2086f6..7537700 100644 --- a/kubi/src/camera/matrices.rs +++ b/kubi/src/camera/matrices.rs @@ -11,7 +11,7 @@ fn update_view_matrix( ) { for (camera, transform) in (&mut vm_camera, v_transform.inserted_or_modified()).iter() { let (_, rotation, translation) = transform.0.to_scale_rotation_translation(); - let direction = rotation * Vec3::NEG_Z; + let direction = (rotation * Vec3::NEG_Z).normalize(); camera.view_matrix = Mat4::look_to_rh(translation, direction, camera.up); } } From 63b4091ddd60bfbcc61626a4d213905521fa86e7 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 1 Feb 2023 23:46:40 +0100 Subject: [PATCH 024/160] only normalize movement if len >= 1 --- kubi/src/fly_controller.rs | 2 +- kubi/src/input.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/kubi/src/fly_controller.rs b/kubi/src/fly_controller.rs index 5b303f4..2822d2a 100644 --- a/kubi/src/fly_controller.rs +++ b/kubi/src/fly_controller.rs @@ -42,7 +42,7 @@ fn update_movement( dt: UniqueView, ) { if inputs.movement == Vec2::ZERO { return } - let movement = inputs.movement.normalize_or_zero() * 30. * dt.0.as_secs_f32(); + let movement = inputs.movement * 30. * dt.0.as_secs_f32(); for (_, mut transform) in (&controllers, &mut transforms).iter() { let (scale, rotation, mut translation) = transform.0.to_scale_rotation_translation(); translation += (rotation * Vec3::NEG_Z).normalize() * movement.y; diff --git a/kubi/src/input.rs b/kubi/src/input.rs index 3e763de..6b92835 100644 --- a/kubi/src/input.rs +++ b/kubi/src/input.rs @@ -111,7 +111,9 @@ fn update_input_state_gamepad ( fn input_end( mut inputs: UniqueViewMut, ) { - inputs.movement = inputs.movement.normalize_or_zero(); + if inputs.movement.length() >= 1. { + inputs.movement = inputs.movement.normalize(); + } } pub fn init_input ( From 99b2848775c1ee75bb00683e23610cab24a7bb21 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 2 Feb 2023 01:40:48 +0100 Subject: [PATCH 025/160] client --- kubi-udp/src/client.rs | 27 ++++++++++++++++++++------- kubi-udp/src/lib.rs | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 320ba2d..892f6ba 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -1,41 +1,54 @@ use std::{ net::{UdpSocket, SocketAddr}, - marker::PhantomData + marker::PhantomData, time::Instant }; use bincode::{Encode, Decode}; use crate::{BINCODE_CONFIG, packet::ClientPacket}; +#[derive(Clone, Copy, Debug)] +pub struct ClientConfig { + +} + pub struct Client where S: Encode + Decode, R: Encode + Decode { + addr: SocketAddr, + config: ClientConfig, socket: UdpSocket, + last_heartbeat: Instant, _s: PhantomData<*const S>, _r: PhantomData<*const R>, } impl Client where S: Encode + Decode, R: Encode + Decode { - pub fn connect(addr: SocketAddr) -> anyhow::Result { + pub fn connect(addr: SocketAddr, config: ClientConfig) -> anyhow::Result { let bind_addr: SocketAddr = "127.0.0.1:0".parse().unwrap(); let socket = UdpSocket::bind(bind_addr)?; socket.set_nonblocking(true)?; socket.connect(addr)?; let client = Self { + addr, + config, socket, + last_heartbeat: Instant::now(), _s: PhantomData, _r: PhantomData, }; - client.send_packet(&ClientPacket::Connect)?; + client.send_raw_packet(&ClientPacket::Connect)?; Ok(client) } - //maybe move generics here if possible? - fn send_packet(&self, packet: &ClientPacket) -> anyhow::Result<()> { + fn send_raw_packet(&self, packet: &ClientPacket) -> anyhow::Result<()> { let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; self.socket.send(&bytes)?; Ok(()) } pub fn send_message(&self, message: S) -> anyhow::Result<()> { - self.send_packet(&ClientPacket::Data(message))?; + self.send_raw_packet(&ClientPacket::Data(message))?; Ok(()) } pub fn disconnect(self) -> anyhow::Result<()> { - self.send_packet(&ClientPacket::Disconnect)?; + self.send_raw_packet(&ClientPacket::Disconnect)?; Ok(()) } + pub fn update(&mut self) { + + } } diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs index caf5110..2790ddc 100644 --- a/kubi-udp/src/lib.rs +++ b/kubi-udp/src/lib.rs @@ -5,6 +5,7 @@ pub(crate) mod packet; pub use server::Server; pub use client::Client; +//pub(crate) trait Serializable: bincode::Encode + bincode::Decode {} pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() .with_little_endian() .with_variable_int_encoding() From 1e1ab9d40ec9a2e14a267bedc4653d847ef20e35 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 2 Feb 2023 01:54:12 +0100 Subject: [PATCH 026/160] wip --- kubi-udp/src/client.rs | 29 ++++++++++++++++++++++------- kubi-udp/src/packet.rs | 10 +++++++++- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 892f6ba..30f3333 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -5,6 +5,13 @@ use std::{ use bincode::{Encode, Decode}; use crate::{BINCODE_CONFIG, packet::ClientPacket}; +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ClientStatus { + Disconnected, + Connecting, + Connected, +} + #[derive(Clone, Copy, Debug)] pub struct ClientConfig { @@ -14,26 +21,34 @@ pub struct Client where S: Encode + Decode, R: Encode + Decode { addr: SocketAddr, config: ClientConfig, socket: UdpSocket, + status: ClientStatus, last_heartbeat: Instant, _s: PhantomData<*const S>, _r: PhantomData<*const R>, } impl Client where S: Encode + Decode, R: Encode + Decode { - pub fn connect(addr: SocketAddr, config: ClientConfig) -> anyhow::Result { + pub fn new(addr: SocketAddr, config: ClientConfig) -> anyhow::Result { let bind_addr: SocketAddr = "127.0.0.1:0".parse().unwrap(); let socket = UdpSocket::bind(bind_addr)?; socket.set_nonblocking(true)?; - socket.connect(addr)?; - let client = Self { + Ok(Self { addr, config, socket, + status: ClientStatus::Disconnected, last_heartbeat: Instant::now(), _s: PhantomData, _r: PhantomData, - }; - client.send_raw_packet(&ClientPacket::Connect)?; - Ok(client) + }) + } + pub fn connect(&mut self) -> anyhow::Result<()> { + if self.status != ClientStatus::Disconnected { + anyhow::bail!("Already {:?}", self.status); + } + self.status = ClientStatus::Connecting; + self.socket.connect(self.addr)?; + self.send_raw_packet(&ClientPacket::Connect)?; + Ok(()) } fn send_raw_packet(&self, packet: &ClientPacket) -> anyhow::Result<()> { let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; @@ -44,7 +59,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.send_raw_packet(&ClientPacket::Data(message))?; Ok(()) } - pub fn disconnect(self) -> anyhow::Result<()> { + pub fn disconnect(&self) -> anyhow::Result<()> { self.send_raw_packet(&ClientPacket::Disconnect)?; Ok(()) } diff --git a/kubi-udp/src/packet.rs b/kubi-udp/src/packet.rs index 49ca38d..eb3505b 100644 --- a/kubi-udp/src/packet.rs +++ b/kubi-udp/src/packet.rs @@ -3,8 +3,16 @@ use bincode::{Encode, Decode}; #[repr(u8)] #[derive(Encode, Decode)] pub enum ClientPacket where T: Encode + Decode { + Data(T), Connect, Disconnect, Heartbeat, - Data(T) +} + +#[repr(u8)] +#[derive(Encode, Decode)] +pub enum ServerPacket where T: Encode + Decode { + Data(T), + Connected, + Disconnected, } From 127460347aeb6a4bb1a906a8ccba911a0859c758 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 2 Feb 2023 02:13:32 +0100 Subject: [PATCH 027/160] client wip --- kubi-udp/src/client.rs | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 30f3333..5ac8c5d 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -1,6 +1,6 @@ use std::{ net::{UdpSocket, SocketAddr}, - marker::PhantomData, time::Instant + marker::PhantomData, time::{Instant, Duration} }; use bincode::{Encode, Decode}; use crate::{BINCODE_CONFIG, packet::ClientPacket}; @@ -14,7 +14,8 @@ pub enum ClientStatus { #[derive(Clone, Copy, Debug)] pub struct ClientConfig { - + pub timeout: Duration, + pub heartbeat_interval: Duration, } pub struct Client where S: Encode + Decode, R: Encode + Decode { @@ -22,6 +23,7 @@ pub struct Client where S: Encode + Decode, R: Encode + Decode { config: ClientConfig, socket: UdpSocket, status: ClientStatus, + timeout: Instant, last_heartbeat: Instant, _s: PhantomData<*const S>, _r: PhantomData<*const R>, @@ -36,6 +38,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { config, socket, status: ClientStatus::Disconnected, + timeout: Instant::now(), last_heartbeat: Instant::now(), _s: PhantomData, _r: PhantomData, @@ -43,9 +46,11 @@ impl Client where S: Encode + Decode, R: Encode + Decode { } pub fn connect(&mut self) -> anyhow::Result<()> { if self.status != ClientStatus::Disconnected { - anyhow::bail!("Already {:?}", self.status); + anyhow::bail!("Not Disconnected"); } self.status = ClientStatus::Connecting; + self.timeout = Instant::now(); + self.last_heartbeat = Instant::now(); self.socket.connect(self.addr)?; self.send_raw_packet(&ClientPacket::Connect)?; Ok(()) @@ -59,11 +64,28 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.send_raw_packet(&ClientPacket::Data(message))?; Ok(()) } - pub fn disconnect(&self) -> anyhow::Result<()> { + pub fn disconnect(&mut self) -> anyhow::Result<()> { + if self.status != ClientStatus::Connected { + anyhow::bail!("Not Connected"); + } self.send_raw_packet(&ClientPacket::Disconnect)?; + self.status = ClientStatus::Disconnected; Ok(()) } - pub fn update(&mut self) { - + pub fn update(&mut self) -> anyhow::Result<()> { + if self.status == ClientStatus::Disconnected { + return Ok(()) + } + if self.timeout.elapsed() > self.config.timeout { + //We don't care if this packet actually gets sent becauseserver is likely dead + let _ = self.send_raw_packet(&ClientPacket::Disconnect); + self.status = ClientStatus::Disconnected; + return Ok(()) + } + if self.last_heartbeat.elapsed() > self.config.heartbeat_interval { + self.send_raw_packet(&ClientPacket::Heartbeat)?; + self.last_heartbeat = Instant::now(); + } + Ok(()) } } From 19bc67a78f8af7f9a5ed3dffde1f63ee20cd1380 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 3 Feb 2023 19:29:38 +0100 Subject: [PATCH 028/160] disconnect reason --- kubi-udp/Cargo.toml | 2 ++ kubi-udp/src/client.rs | 35 ++++++++++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/kubi-udp/Cargo.toml b/kubi-udp/Cargo.toml index 8a64827..f99b6ad 100644 --- a/kubi-udp/Cargo.toml +++ b/kubi-udp/Cargo.toml @@ -8,3 +8,5 @@ edition = "2021" [dependencies] bincode = "2.0.0-rc" anyhow = "1.0" +nohash-hasher = "0.2.0" +log = "0.4" diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 5ac8c5d..0538c43 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -18,6 +18,19 @@ pub struct ClientConfig { pub heartbeat_interval: Duration, } +pub type ClientId = u8; + +#[derive(Default, Encode, Decode)] +#[repr(u8)] +pub enum DisconnectReason { + #[default] + NotConnected, + ClientDisconnected, + KickedByServer, + ClientTimeout, + ServerTimeout, +} + pub struct Client where S: Encode + Decode, R: Encode + Decode { addr: SocketAddr, config: ClientConfig, @@ -25,6 +38,8 @@ pub struct Client where S: Encode + Decode, R: Encode + Decode { status: ClientStatus, timeout: Instant, last_heartbeat: Instant, + client_id: Option, + disconnect_reason: DisconnectReason, _s: PhantomData<*const S>, _r: PhantomData<*const R>, } @@ -40,6 +55,8 @@ impl Client where S: Encode + Decode, R: Encode + Decode { status: ClientStatus::Disconnected, timeout: Instant::now(), last_heartbeat: Instant::now(), + client_id: None, + disconnect_reason: DisconnectReason::default(), _s: PhantomData, _r: PhantomData, }) @@ -64,12 +81,17 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.send_raw_packet(&ClientPacket::Data(message))?; Ok(()) } + fn disconnect_inner(&mut self, reason: DisconnectReason) -> anyhow::Result<()> { + self.send_raw_packet(&ClientPacket::Disconnect)?; + self.status = ClientStatus::Disconnected; + self.disconnect_reason = DisconnectReason::ClientDisconnected; + Ok(()) + } pub fn disconnect(&mut self) -> anyhow::Result<()> { if self.status != ClientStatus::Connected { anyhow::bail!("Not Connected"); } - self.send_raw_packet(&ClientPacket::Disconnect)?; - self.status = ClientStatus::Disconnected; + self.disconnect_inner(DisconnectReason::ClientDisconnected)?; Ok(()) } pub fn update(&mut self) -> anyhow::Result<()> { @@ -77,12 +99,15 @@ impl Client where S: Encode + Decode, R: Encode + Decode { return Ok(()) } if self.timeout.elapsed() > self.config.timeout { - //We don't care if this packet actually gets sent becauseserver is likely dead - let _ = self.send_raw_packet(&ClientPacket::Disconnect); - self.status = ClientStatus::Disconnected; + log::warn!("Client timed out"); + //We don't care if this packet actually gets sent because the server is likely dead + let _ = self.disconnect_inner(DisconnectReason::ClientDisconnected).map_err(|_| { + log::warn!("Failed to send disconnect packet"); + }); return Ok(()) } if self.last_heartbeat.elapsed() > self.config.heartbeat_interval { + log::trace!("Sending heartbeat packet"); self.send_raw_packet(&ClientPacket::Heartbeat)?; self.last_heartbeat = Instant::now(); } From a1ff9e1d3077468dca1b7c49166df650c1f8e8c8 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 3 Feb 2023 19:36:52 +0100 Subject: [PATCH 029/160] id packets --- kubi-udp/src/client.rs | 32 ++++++++++++-------------------- kubi-udp/src/common.rs | 15 +++++++++++++++ kubi-udp/src/lib.rs | 8 +++----- kubi-udp/src/packet.rs | 4 ++++ 4 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 kubi-udp/src/common.rs diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 0538c43..fd96620 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -3,7 +3,11 @@ use std::{ marker::PhantomData, time::{Instant, Duration} }; use bincode::{Encode, Decode}; -use crate::{BINCODE_CONFIG, packet::ClientPacket}; +use crate::{ + BINCODE_CONFIG, + packet::{ClientPacket, IdClientPacket}, + common::{ClientId, DisconnectReason} +}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ClientStatus { @@ -18,19 +22,6 @@ pub struct ClientConfig { pub heartbeat_interval: Duration, } -pub type ClientId = u8; - -#[derive(Default, Encode, Decode)] -#[repr(u8)] -pub enum DisconnectReason { - #[default] - NotConnected, - ClientDisconnected, - KickedByServer, - ClientTimeout, - ServerTimeout, -} - pub struct Client where S: Encode + Decode, R: Encode + Decode { addr: SocketAddr, config: ClientConfig, @@ -69,20 +60,21 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.timeout = Instant::now(); self.last_heartbeat = Instant::now(); self.socket.connect(self.addr)?; - self.send_raw_packet(&ClientPacket::Connect)?; + self.send_raw_packet(ClientPacket::Connect)?; Ok(()) } - fn send_raw_packet(&self, packet: &ClientPacket) -> anyhow::Result<()> { - let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; + fn send_raw_packet(&self, packet: ClientPacket) -> anyhow::Result<()> { + let id_packet = IdClientPacket(self.client_id, packet); + let bytes = bincode::encode_to_vec(id_packet, BINCODE_CONFIG)?; self.socket.send(&bytes)?; Ok(()) } pub fn send_message(&self, message: S) -> anyhow::Result<()> { - self.send_raw_packet(&ClientPacket::Data(message))?; + self.send_raw_packet(ClientPacket::Data(message))?; Ok(()) } fn disconnect_inner(&mut self, reason: DisconnectReason) -> anyhow::Result<()> { - self.send_raw_packet(&ClientPacket::Disconnect)?; + self.send_raw_packet(ClientPacket::Disconnect)?; self.status = ClientStatus::Disconnected; self.disconnect_reason = DisconnectReason::ClientDisconnected; Ok(()) @@ -108,7 +100,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { } if self.last_heartbeat.elapsed() > self.config.heartbeat_interval { log::trace!("Sending heartbeat packet"); - self.send_raw_packet(&ClientPacket::Heartbeat)?; + self.send_raw_packet(ClientPacket::Heartbeat)?; self.last_heartbeat = Instant::now(); } Ok(()) diff --git a/kubi-udp/src/common.rs b/kubi-udp/src/common.rs new file mode 100644 index 0000000..ec4b097 --- /dev/null +++ b/kubi-udp/src/common.rs @@ -0,0 +1,15 @@ +use std::num::NonZeroU8; +use bincode::{Encode, Decode}; + +pub type ClientId = NonZeroU8; + +#[derive(Default, Encode, Decode)] +#[repr(u8)] +pub enum DisconnectReason { + #[default] + NotConnected, + ClientDisconnected, + KickedByServer, + ClientTimeout, + ServerTimeout, +} diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs index 2790ddc..b906e02 100644 --- a/kubi-udp/src/lib.rs +++ b/kubi-udp/src/lib.rs @@ -1,9 +1,7 @@ -pub(crate) mod client; -pub(crate) mod server; +pub mod client; +pub mod server; pub(crate) mod packet; - -pub use server::Server; -pub use client::Client; +pub(crate) mod common; //pub(crate) trait Serializable: bincode::Encode + bincode::Decode {} pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() diff --git a/kubi-udp/src/packet.rs b/kubi-udp/src/packet.rs index eb3505b..8b5b8d2 100644 --- a/kubi-udp/src/packet.rs +++ b/kubi-udp/src/packet.rs @@ -1,4 +1,5 @@ use bincode::{Encode, Decode}; +use crate::common::ClientId; #[repr(u8)] #[derive(Encode, Decode)] @@ -9,6 +10,9 @@ pub enum ClientPacket where T: Encode + Decode { Heartbeat, } +#[derive(Encode, Decode)] +pub struct IdClientPacket(pub Option, pub ClientPacket); + #[repr(u8)] #[derive(Encode, Decode)] pub enum ServerPacket where T: Encode + Decode { From 1ca847b4fcc8daffc1b84e721a4b07e9639a684e Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 3 Feb 2023 19:39:22 +0100 Subject: [PATCH 030/160] use anyhow::{...} --- kubi-udp/src/client.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index fd96620..1551723 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -1,3 +1,4 @@ +use anyhow::{Result, bail}; use std::{ net::{UdpSocket, SocketAddr}, marker::PhantomData, time::{Instant, Duration} @@ -35,7 +36,7 @@ pub struct Client where S: Encode + Decode, R: Encode + Decode { _r: PhantomData<*const R>, } impl Client where S: Encode + Decode, R: Encode + Decode { - pub fn new(addr: SocketAddr, config: ClientConfig) -> anyhow::Result { + pub fn new(addr: SocketAddr, config: ClientConfig) -> Result { let bind_addr: SocketAddr = "127.0.0.1:0".parse().unwrap(); let socket = UdpSocket::bind(bind_addr)?; socket.set_nonblocking(true)?; @@ -52,9 +53,9 @@ impl Client where S: Encode + Decode, R: Encode + Decode { _r: PhantomData, }) } - pub fn connect(&mut self) -> anyhow::Result<()> { + pub fn connect(&mut self) -> Result<()> { if self.status != ClientStatus::Disconnected { - anyhow::bail!("Not Disconnected"); + bail!("Not Disconnected"); } self.status = ClientStatus::Connecting; self.timeout = Instant::now(); @@ -63,30 +64,30 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.send_raw_packet(ClientPacket::Connect)?; Ok(()) } - fn send_raw_packet(&self, packet: ClientPacket) -> anyhow::Result<()> { + fn send_raw_packet(&self, packet: ClientPacket) -> Result<()> { let id_packet = IdClientPacket(self.client_id, packet); let bytes = bincode::encode_to_vec(id_packet, BINCODE_CONFIG)?; self.socket.send(&bytes)?; Ok(()) } - pub fn send_message(&self, message: S) -> anyhow::Result<()> { + pub fn send_message(&self, message: S) -> Result<()> { self.send_raw_packet(ClientPacket::Data(message))?; Ok(()) } - fn disconnect_inner(&mut self, reason: DisconnectReason) -> anyhow::Result<()> { + fn disconnect_inner(&mut self, reason: DisconnectReason) -> Result<()> { self.send_raw_packet(ClientPacket::Disconnect)?; self.status = ClientStatus::Disconnected; - self.disconnect_reason = DisconnectReason::ClientDisconnected; + self.disconnect_reason = reason; Ok(()) } - pub fn disconnect(&mut self) -> anyhow::Result<()> { + pub fn disconnect(&mut self) -> Result<()> { if self.status != ClientStatus::Connected { - anyhow::bail!("Not Connected"); + bail!("Not Connected"); } self.disconnect_inner(DisconnectReason::ClientDisconnected)?; Ok(()) } - pub fn update(&mut self) -> anyhow::Result<()> { + pub fn update(&mut self) -> Result<()> { if self.status == ClientStatus::Disconnected { return Ok(()) } From 4ac6250c0440ea1db36ae8c2ddac6ea4bfdb832e Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sat, 4 Feb 2023 02:46:48 +0100 Subject: [PATCH 031/160] client is almost finished... --- kubi-udp/src/client.rs | 95 ++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 23 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 1551723..4bddda6 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -1,12 +1,13 @@ use anyhow::{Result, bail}; use std::{ net::{UdpSocket, SocketAddr}, - marker::PhantomData, time::{Instant, Duration} + time::{Instant, Duration}, + marker::PhantomData, }; use bincode::{Encode, Decode}; use crate::{ BINCODE_CONFIG, - packet::{ClientPacket, IdClientPacket}, + packet::{ClientPacket, IdClientPacket, IdServerPacket, ServerPacket}, common::{ClientId, DisconnectReason} }; @@ -24,8 +25,8 @@ pub struct ClientConfig { } pub struct Client where S: Encode + Decode, R: Encode + Decode { + pub config: ClientConfig, addr: SocketAddr, - config: ClientConfig, socket: UdpSocket, status: ClientStatus, timeout: Instant, @@ -53,48 +54,65 @@ impl Client where S: Encode + Decode, R: Encode + Decode { _r: PhantomData, }) } - pub fn connect(&mut self) -> Result<()> { - if self.status != ClientStatus::Disconnected { - bail!("Not Disconnected"); - } - self.status = ClientStatus::Connecting; - self.timeout = Instant::now(); - self.last_heartbeat = Instant::now(); - self.socket.connect(self.addr)?; - self.send_raw_packet(ClientPacket::Connect)?; - Ok(()) - } + fn send_raw_packet(&self, packet: ClientPacket) -> Result<()> { let id_packet = IdClientPacket(self.client_id, packet); let bytes = bincode::encode_to_vec(id_packet, BINCODE_CONFIG)?; self.socket.send(&bytes)?; Ok(()) } - pub fn send_message(&self, message: S) -> Result<()> { - self.send_raw_packet(ClientPacket::Data(message))?; - Ok(()) - } - fn disconnect_inner(&mut self, reason: DisconnectReason) -> Result<()> { - self.send_raw_packet(ClientPacket::Disconnect)?; + + fn disconnect_inner(&mut self, reason: DisconnectReason, silent: bool) -> Result<()> { + if !silent { + self.send_raw_packet(ClientPacket::Disconnect)?; + } + self.client_id = None; self.status = ClientStatus::Disconnected; self.disconnect_reason = reason; Ok(()) } + + fn reset_timeout(&mut self) { + self.timeout = Instant::now(); + } + + + pub fn connect(&mut self) -> Result<()> { + if self.status != ClientStatus::Disconnected { + bail!("Not Disconnected"); + } + self.status = ClientStatus::Connecting; + self.last_heartbeat = Instant::now(); + self.reset_timeout(); + self.socket.connect(self.addr)?; + self.send_raw_packet(ClientPacket::Connect)?; + Ok(()) + } + pub fn disconnect(&mut self) -> Result<()> { if self.status != ClientStatus::Connected { bail!("Not Connected"); } - self.disconnect_inner(DisconnectReason::ClientDisconnected)?; + self.disconnect_inner(DisconnectReason::ClientDisconnected, false)?; Ok(()) } - pub fn update(&mut self) -> Result<()> { + + pub fn send_message(&self, message: S) -> Result<()> { + if self.status != ClientStatus::Connected { + bail!("Not Connected"); + } + self.send_raw_packet(ClientPacket::Data(message))?; + Ok(()) + } + + pub fn update(&mut self, callback: fn(R) -> Result<()>) -> Result<()> { if self.status == ClientStatus::Disconnected { return Ok(()) } if self.timeout.elapsed() > self.config.timeout { log::warn!("Client timed out"); //We don't care if this packet actually gets sent because the server is likely dead - let _ = self.disconnect_inner(DisconnectReason::ClientDisconnected).map_err(|_| { + let _ = self.disconnect_inner(DisconnectReason::ClientDisconnected, false).map_err(|_| { log::warn!("Failed to send disconnect packet"); }); return Ok(()) @@ -104,6 +122,37 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.send_raw_packet(ClientPacket::Heartbeat)?; self.last_heartbeat = Instant::now(); } + //receive + let mut buf = Vec::new(); + loop { + if self.socket.recv(&mut buf).is_ok() { + //TODO check the first byte of the raw data instead of decoding? + let (packet, _): (IdServerPacket, _) = bincode::decode_from_slice(&buf, BINCODE_CONFIG)?; + let IdServerPacket(user_id, packet) = packet; + if self.client_id.map(|x| Some(x) != user_id).unwrap_or_default() { + continue + } + self.reset_timeout(); + match packet { + ServerPacket::Connected(client_id) => { + self.client_id = Some(client_id); + self.status = ClientStatus::Connected; + return Ok(()) + }, + ServerPacket::Disconnected => { + //this should never fail but we're handling the error anyway + self.disconnect_inner(DisconnectReason::KickedByServer, true)?; + return Ok(()) + }, + ServerPacket::Data(message) => { + callback(message)?; + } + } + } else { + break + } + buf.clear(); + } Ok(()) } } From eff0b505468bf751e5f6b82bdd301410e96c9665 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sat, 4 Feb 2023 02:47:09 +0100 Subject: [PATCH 032/160] . --- kubi-udp/src/packet.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kubi-udp/src/packet.rs b/kubi-udp/src/packet.rs index 8b5b8d2..d824d2c 100644 --- a/kubi-udp/src/packet.rs +++ b/kubi-udp/src/packet.rs @@ -17,6 +17,9 @@ pub struct IdClientPacket(pub Option, pub ClientPa #[derive(Encode, Decode)] pub enum ServerPacket where T: Encode + Decode { Data(T), - Connected, + Connected(ClientId), Disconnected, } + +#[derive(Encode, Decode)] +pub struct IdServerPacket(pub Option, pub ServerPacket); From c1f1ec028fc8b0be561f893ef4dbbd80c4124d43 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sat, 4 Feb 2023 22:20:19 +0100 Subject: [PATCH 033/160] add kick reason --- kubi-udp/src/client.rs | 5 +++-- kubi-udp/src/common.rs | 2 +- kubi-udp/src/packet.rs | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 4bddda6..55d0917 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -139,9 +139,10 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.status = ClientStatus::Connected; return Ok(()) }, - ServerPacket::Disconnected => { + ServerPacket::Disconnected(reason) => { //this should never fail but we're handling the error anyway - self.disconnect_inner(DisconnectReason::KickedByServer, true)?; + let reason = DisconnectReason::KickedByServer(reason); + self.disconnect_inner(reason, true)?; return Ok(()) }, ServerPacket::Data(message) => { diff --git a/kubi-udp/src/common.rs b/kubi-udp/src/common.rs index ec4b097..83a40ef 100644 --- a/kubi-udp/src/common.rs +++ b/kubi-udp/src/common.rs @@ -9,7 +9,7 @@ pub enum DisconnectReason { #[default] NotConnected, ClientDisconnected, - KickedByServer, + KickedByServer(String), ClientTimeout, ServerTimeout, } diff --git a/kubi-udp/src/packet.rs b/kubi-udp/src/packet.rs index d824d2c..8f13403 100644 --- a/kubi-udp/src/packet.rs +++ b/kubi-udp/src/packet.rs @@ -18,7 +18,7 @@ pub struct IdClientPacket(pub Option, pub ClientPa pub enum ServerPacket where T: Encode + Decode { Data(T), Connected(ClientId), - Disconnected, + Disconnected(String), } #[derive(Encode, Decode)] From 53fc7dcd277ad5cffa75370712258de860fa30cf Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sat, 4 Feb 2023 22:27:19 +0100 Subject: [PATCH 034/160] comment --- kubi-udp/src/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 55d0917..8707e18 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -140,8 +140,8 @@ impl Client where S: Encode + Decode, R: Encode + Decode { return Ok(()) }, ServerPacket::Disconnected(reason) => { - //this should never fail but we're handling the error anyway let reason = DisconnectReason::KickedByServer(reason); + //this should never fail but we're handling the error anyway self.disconnect_inner(reason, true)?; return Ok(()) }, From 00f54a2f5f3b8570ec6bb53050f07058e751fda8 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 5 Feb 2023 00:42:37 +0100 Subject: [PATCH 035/160] wip block queue --- kubi/src/world.rs | 1 + kubi/src/world/queue.rs | 45 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 kubi/src/world/queue.rs diff --git a/kubi/src/world.rs b/kubi/src/world.rs index 518fee7..355d33b 100644 --- a/kubi/src/world.rs +++ b/kubi/src/world.rs @@ -13,6 +13,7 @@ pub mod loading; pub mod mesh; pub mod neighbors; pub mod raycast; +pub mod queue; use chunk::{Chunk, ChunkMesh}; use tasks::ChunkTaskManager; diff --git a/kubi/src/world/queue.rs b/kubi/src/world/queue.rs new file mode 100644 index 0000000..31c9f79 --- /dev/null +++ b/kubi/src/world/queue.rs @@ -0,0 +1,45 @@ +use std::collections::VecDeque; +use glam::IVec3; +use kubi_shared::blocks::Block; +use shipyard::{UniqueViewMut, Unique}; + +use super::ChunkStorage; + +#[derive(Clone, Copy, Debug)] +pub struct BlockUpdateEvent { + pub position: IVec3, + pub value: Block +} + +#[derive(Unique, Default, Clone)] +pub struct BlockUpdateQueue { + queue: VecDeque +} +impl BlockUpdateQueue { + pub fn new() -> Self { + Self::default() + } + pub fn push(&mut self, event: BlockUpdateEvent) { + self.queue.push_back(event) + } + pub fn pop(&mut self) -> Option { + self.queue.pop_front() + } + pub fn clear(&mut self) { + self.queue.clear(); + } +} + +pub fn apply_events( + mut queue: UniqueViewMut, + mut world: UniqueViewMut +) { + while let Some(event) = queue.pop() { + if let Some(block) = world.get_block_mut(event.position) { + let (chunk_pos, _) = ChunkStorage::to_chunk_coords(event.position); + let chunk = world.chunks.get_mut(&chunk_pos).expect("This error should never happen, if it does then something is super fucked up and the whole project needs to be burnt down."); + chunk.dirty = true; + } + + } +} From 319cffbb4e7ee5025fd758a9b6c0e836f800489a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 5 Feb 2023 00:58:25 +0100 Subject: [PATCH 036/160] block queue works --- kubi/src/block_placement.rs | 23 ++++++++++------------- kubi/src/main.rs | 3 ++- kubi/src/world.rs | 7 ++++--- kubi/src/world/chunk.rs | 4 ++-- kubi/src/world/loading.rs | 6 +++--- kubi/src/world/queue.rs | 25 +++++++++++-------------- 6 files changed, 32 insertions(+), 36 deletions(-) diff --git a/kubi/src/block_placement.rs b/kubi/src/block_placement.rs index aec44a3..f46ff1b 100644 --- a/kubi/src/block_placement.rs +++ b/kubi/src/block_placement.rs @@ -1,7 +1,7 @@ use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut}; use crate::{ player::MainPlayer, - world::{raycast::LookingAtBlock, ChunkStorage, block::Block}, + world::{raycast::LookingAtBlock, ChunkStorage, block::Block, queue::{BlockUpdateQueue, BlockUpdateEvent}}, input::{Inputs, PrevInputs}, events::{EventComponent, player_actions::PlayerActionEvent}, }; @@ -11,7 +11,7 @@ pub fn block_placement_system( raycast: View, input: UniqueView, prev_input: UniqueView, - mut world: UniqueViewMut, + mut block_event_queue: UniqueViewMut, mut entities: EntitiesViewMut, mut events: ViewMut, mut player_events: ViewMut, @@ -21,21 +21,18 @@ pub fn block_placement_system( if action_place ^ action_break { //get raycast info let Some(ray) = (&main_player, &raycast).iter().next().unwrap().1/**/.0 else { return }; - //update block + //get coord and block type let (place_position, place_block) = if action_place { let position = (ray.position - ray.direction * 0.5).floor().as_ivec3(); - let Some(block) = world.get_block_mut(position) else { return }; - *block = Block::Dirt; - (position, *block) + (position, Block::Dirt) } else { - let Some(block) = world.get_block_mut(ray.block_position) else { return }; - *block = Block::Air; - (ray.block_position, *block) + (ray.block_position, Block::Air) }; - //mark chunk as dirty - let (chunk_pos, _) = ChunkStorage::to_chunk_coords(place_position); - let chunk = world.chunks.get_mut(&chunk_pos).unwrap(); - chunk.dirty = true; + //queue place + block_event_queue.push(BlockUpdateEvent { + position: place_position, + value: place_block, + }); //send event entities.add_entity( (&mut events, &mut player_events), diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 68a3e31..6af453e 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -35,7 +35,7 @@ pub(crate) mod control_flow; use world::{ init_game_world, loading::update_loaded_world_around_player, - raycast::update_raycasts + raycast::update_raycasts, queue::apply_queued_blocks }; use player::spawn_player; use prefabs::load_prefabs; @@ -84,6 +84,7 @@ fn update() -> Workload { update_loaded_world_around_player, update_raycasts, block_placement_system, + apply_queued_blocks, update_cursor_lock_state, compute_cameras, exit_on_esc, diff --git a/kubi/src/world.rs b/kubi/src/world.rs index 355d33b..4d8684d 100644 --- a/kubi/src/world.rs +++ b/kubi/src/world.rs @@ -15,10 +15,10 @@ pub mod neighbors; pub mod raycast; pub mod queue; -use chunk::{Chunk, ChunkMesh}; +use block::Block; +use chunk::{Chunk, ChunkMesh, CHUNK_SIZE}; use tasks::ChunkTaskManager; - -use self::{chunk::CHUNK_SIZE, block::Block}; +use queue::BlockUpdateQueue; //TODO separate world struct for render data // because this is not send-sync @@ -111,4 +111,5 @@ pub fn init_game_world( storages.add_unique_non_send_sync(ChunkMeshStorage::new()); storages.add_unique(ChunkStorage::new()); storages.add_unique(ChunkTaskManager::new()); + storages.add_unique(BlockUpdateQueue::new()); } diff --git a/kubi/src/world/chunk.rs b/kubi/src/world/chunk.rs index 285ab44..7d3733d 100644 --- a/kubi/src/world/chunk.rs +++ b/kubi/src/world/chunk.rs @@ -46,7 +46,7 @@ pub struct Chunk { pub mesh_index: Option, pub current_state: CurrentChunkState, pub desired_state: DesiredChunkState, - pub dirty: bool, + pub mesh_dirty: bool, } impl Chunk { pub fn new(position: IVec3) -> Self { @@ -56,7 +56,7 @@ impl Chunk { mesh_index: None, current_state: Default::default(), desired_state: Default::default(), - dirty: false, + mesh_dirty: false, } } } diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index 28ec501..7320f3b 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -138,7 +138,7 @@ fn start_required_tasks( // =========== //log::trace!("Started loading chunk {position}"); }, - DesiredChunkState::Rendered if (chunk.current_state == CurrentChunkState::Loaded || chunk.dirty) => { + DesiredChunkState::Rendered if (chunk.current_state == CurrentChunkState::Loaded || chunk.mesh_dirty) => { //get needed data let Some(neighbors) = world.neighbors_all(position) else { continue @@ -150,12 +150,12 @@ fn start_required_tasks( task_manager.spawn_task(ChunkTask::GenerateMesh { data, position }); //Update chunk state let chunk = world.chunks.get_mut(&position).unwrap(); - if chunk.dirty { + if chunk.mesh_dirty { chunk.current_state = CurrentChunkState::RecalculatingMesh; } else { chunk.current_state = CurrentChunkState::CalculatingMesh; } - chunk.dirty = false; + chunk.mesh_dirty = false; // =========== //log::trace!("Started generating mesh for chunk {position}"); } diff --git a/kubi/src/world/queue.rs b/kubi/src/world/queue.rs index 31c9f79..51adede 100644 --- a/kubi/src/world/queue.rs +++ b/kubi/src/world/queue.rs @@ -1,4 +1,3 @@ -use std::collections::VecDeque; use glam::IVec3; use kubi_shared::blocks::Block; use shipyard::{UniqueViewMut, Unique}; @@ -13,33 +12,31 @@ pub struct BlockUpdateEvent { #[derive(Unique, Default, Clone)] pub struct BlockUpdateQueue { - queue: VecDeque + queue: Vec } impl BlockUpdateQueue { pub fn new() -> Self { Self::default() } pub fn push(&mut self, event: BlockUpdateEvent) { - self.queue.push_back(event) - } - pub fn pop(&mut self) -> Option { - self.queue.pop_front() - } - pub fn clear(&mut self) { - self.queue.clear(); + self.queue.push(event) } } -pub fn apply_events( +pub fn apply_queued_blocks( mut queue: UniqueViewMut, mut world: UniqueViewMut ) { - while let Some(event) = queue.pop() { + queue.queue.retain(|&event| { if let Some(block) = world.get_block_mut(event.position) { + *block = event.value; + //mark chunk as dirty + //maybe i need to check for desired/current state here? let (chunk_pos, _) = ChunkStorage::to_chunk_coords(event.position); let chunk = world.chunks.get_mut(&chunk_pos).expect("This error should never happen, if it does then something is super fucked up and the whole project needs to be burnt down."); - chunk.dirty = true; + chunk.mesh_dirty = true; + return false } - - } + true + }); } From 34fa47acbef045162a330f047d328f9f14c0340b Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 5 Feb 2023 01:18:30 +0100 Subject: [PATCH 037/160] Update neighbors --- kubi/src/world/queue.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/kubi/src/world/queue.rs b/kubi/src/world/queue.rs index 51adede..bfcaa63 100644 --- a/kubi/src/world/queue.rs +++ b/kubi/src/world/queue.rs @@ -1,5 +1,5 @@ -use glam::IVec3; -use kubi_shared::blocks::Block; +use glam::{IVec3, ivec3}; +use kubi_shared::{blocks::Block, chunk::CHUNK_SIZE}; use shipyard::{UniqueViewMut, Unique}; use super::ChunkStorage; @@ -27,14 +27,33 @@ pub fn apply_queued_blocks( mut queue: UniqueViewMut, mut world: UniqueViewMut ) { + //maybe i need to check for desired/current state here before marking as dirty? queue.queue.retain(|&event| { if let Some(block) = world.get_block_mut(event.position) { *block = event.value; //mark chunk as dirty - //maybe i need to check for desired/current state here? - let (chunk_pos, _) = ChunkStorage::to_chunk_coords(event.position); + let (chunk_pos, block_pos) = ChunkStorage::to_chunk_coords(event.position); let chunk = world.chunks.get_mut(&chunk_pos).expect("This error should never happen, if it does then something is super fucked up and the whole project needs to be burnt down."); chunk.mesh_dirty = true; + //If block pos is close to the border, some neighbors may be dirty! + const DIRECTIONS: [IVec3; 6] = [ + ivec3(1, 0, 0), + ivec3(-1, 0, 0), + ivec3(0, 1, 0), + ivec3(0, -1, 0), + ivec3(0, 0, 1), + ivec3(0, 0, -1), + ]; + for direction in DIRECTIONS { + let outside_chunk = |x| !(0..CHUNK_SIZE as i32).contains(x); + let chunk_dirty = (block_pos + direction).to_array().iter().any(outside_chunk); + if chunk_dirty { + let dir_chunk_pos = chunk_pos + direction; + if let Some(dir_chunk) = world.chunks.get_mut(&dir_chunk_pos) { + dir_chunk.mesh_dirty = true; + } + } + } return false } true From df8640718d8b88fcd0c08c8b08d21fbb88176a64 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 5 Feb 2023 01:22:43 +0100 Subject: [PATCH 038/160] don't count discarded ops --- kubi/src/world/loading.rs | 112 ++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 52 deletions(-) diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index 7320f3b..a248857 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -170,61 +170,69 @@ fn process_completed_tasks( mut meshes: NonSendSync>, renderer: NonSendSync> ) { - for _ in 0..MAX_CHUNK_OPS { - if let Some(res) = task_manager.receive() { - match res { - ChunkTaskResponse::LoadedChunk { position, chunk_data } => { - //check if chunk exists - let Some(chunk) = world.chunks.get_mut(&position) else { - log::warn!("blocks data discarded: chunk doesn't exist"); - return - }; + let mut ops: usize = 0; + while let Some(res) = task_manager.receive() { + match res { + ChunkTaskResponse::LoadedChunk { position, chunk_data } => { + //check if chunk exists + let Some(chunk) = world.chunks.get_mut(&position) else { + log::warn!("blocks data discarded: chunk doesn't exist"); + return + }; - //check if chunk still wants it - if !matches!(chunk.desired_state, DesiredChunkState::Loaded | DesiredChunkState::Rendered) { - log::warn!("block data discarded: state undesirable: {:?}", chunk.desired_state); - return - } - - //set the block data - chunk.block_data = Some(ChunkData { - blocks: chunk_data - }); - - //update chunk state - chunk.current_state = CurrentChunkState::Loaded; - }, - ChunkTaskResponse::GeneratedMesh { position, vertices, indexes } => { - //check if chunk exists - let Some(chunk) = world.chunks.get_mut(&position) else { - log::warn!("mesh discarded: chunk doesn't exist"); - return - }; - - //check if chunk still wants it - if chunk.desired_state != DesiredChunkState::Rendered { - log::warn!("mesh discarded: state undesirable: {:?}", chunk.desired_state); - return - } - - //apply the mesh - let vertex_buffer = VertexBuffer::new(&renderer.display, &vertices).unwrap(); - let index_buffer = IndexBuffer::new(&renderer.display, PrimitiveType::TrianglesList, &indexes).unwrap(); - let mesh = ChunkMesh { - vertex_buffer, - index_buffer, - }; - if let Some(index) = chunk.mesh_index { - meshes.update(index, mesh).expect("Mesh update failed"); - } else { - let mesh_index = meshes.insert(mesh); - chunk.mesh_index = Some(mesh_index); - } - - //update chunk state - chunk.current_state = CurrentChunkState::Rendered; + //check if chunk still wants it + if !matches!(chunk.desired_state, DesiredChunkState::Loaded | DesiredChunkState::Rendered) { + log::warn!("block data discarded: state undesirable: {:?}", chunk.desired_state); + return } + + //set the block data + chunk.block_data = Some(ChunkData { + blocks: chunk_data + }); + + //update chunk state + chunk.current_state = CurrentChunkState::Loaded; + + //increase ops counter + ops += 1; + }, + ChunkTaskResponse::GeneratedMesh { position, vertices, indexes } => { + //check if chunk exists + let Some(chunk) = world.chunks.get_mut(&position) else { + log::warn!("mesh discarded: chunk doesn't exist"); + return + }; + + //check if chunk still wants it + if chunk.desired_state != DesiredChunkState::Rendered { + log::warn!("mesh discarded: state undesirable: {:?}", chunk.desired_state); + return + } + + //apply the mesh + let vertex_buffer = VertexBuffer::new(&renderer.display, &vertices).unwrap(); + let index_buffer = IndexBuffer::new(&renderer.display, PrimitiveType::TrianglesList, &indexes).unwrap(); + let mesh = ChunkMesh { + vertex_buffer, + index_buffer, + }; + if let Some(index) = chunk.mesh_index { + meshes.update(index, mesh).expect("Mesh update failed"); + } else { + let mesh_index = meshes.insert(mesh); + chunk.mesh_index = Some(mesh_index); + } + + //update chunk state + chunk.current_state = CurrentChunkState::Rendered; + + //increase ops counter + ops += 1; } } + if ops >= MAX_CHUNK_OPS { + break + } } } From 01b82b1094c02ec5e7dcfde5e6ff16af01217420 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 5 Feb 2023 01:43:47 +0100 Subject: [PATCH 039/160] cobblestone --- assets/blocks/cobblestone.png | Bin 0 -> 578 bytes kubi-shared/src/blocks.rs | 1 + kubi/src/block_placement.rs | 2 +- kubi/src/prefabs.rs | 28 +++++++++++++++------------- kubi/src/world/block.rs | 6 ++++++ 5 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 assets/blocks/cobblestone.png diff --git a/assets/blocks/cobblestone.png b/assets/blocks/cobblestone.png new file mode 100644 index 0000000000000000000000000000000000000000..44b13240dd83efdbea89d62a1281ceebb28b33c2 GIT binary patch literal 578 zcmV-I0=@l-P)Px#1ZP1_K>z@;j|==^1poj5=TJ;kMS6OAVPRokUtg`Qt)`}?e0+RuZEc^QpL=_I zPft%*S66CkYNMm0hK7czsi}m7gk)r7gM)*Lii(Sii(p`2prD|got<}gcaM*cf`Wom zQ&W_blz@PMn3$MuZf<^levFKaRaI4@qN0|TmStsSO-)TwQc{y`Ts;a8Iyu6#6n{;$^T3T9}nVEloe}#pGj*X6Xc6M=baY{-`Nl8hhq@pF^9aqcZLu)}@8|7vT?G7n8>5{IVl07S-ei%i5nT;CKKll7Tr%dWDrRjWDm1$1pu4#Mdrz4n%mQ}`7dGC zPTZ_6P}MN2y{f(~2dgy%4A_h}iRzNu!ixLuGX{1Z8ShnRVte!8OlBXSz__<4N~fd# zmvn~T3h3eBiBoL_(LUbf2SImElg-Lu&Pw+4ODxUS()ddQTD|y;cO6Ce4+EtbXY+DM Ql>h($07*qoM6N<$g5jz9)&Kwi literal 0 HcmV?d00001 diff --git a/kubi-shared/src/blocks.rs b/kubi-shared/src/blocks.rs index 3e601fc..0f94b33 100644 --- a/kubi-shared/src/blocks.rs +++ b/kubi-shared/src/blocks.rs @@ -9,4 +9,5 @@ pub enum Block { Dirt, Grass, Sand, + Cobblestone, } diff --git a/kubi/src/block_placement.rs b/kubi/src/block_placement.rs index f46ff1b..3eff4be 100644 --- a/kubi/src/block_placement.rs +++ b/kubi/src/block_placement.rs @@ -24,7 +24,7 @@ pub fn block_placement_system( //get coord and block type let (place_position, place_block) = if action_place { let position = (ray.position - ray.direction * 0.5).floor().as_ivec3(); - (position, Block::Dirt) + (position, Block::Cobblestone) } else { (ray.block_position, Block::Air) }; diff --git a/kubi/src/prefabs.rs b/kubi/src/prefabs.rs index 8b90291..4529bce 100644 --- a/kubi/src/prefabs.rs +++ b/kubi/src/prefabs.rs @@ -16,19 +16,20 @@ pub trait AssetPaths { #[derive(Clone, Copy, Debug, EnumIter)] #[repr(u8)] pub enum BlockTexture { - Stone = 0, - Dirt = 1, - GrassTop = 2, - GrassSide = 3, - Sand = 4, - Bedrock = 5, - Wood = 6, - WoodTop = 7, - Leaf = 8, - Torch = 9, - TallGrass = 10, - Snow = 11, - GrassSideSnow = 12, + Stone, + Dirt, + GrassTop, + GrassSide, + Sand, + Bedrock, + Wood, + WoodTop, + Leaf, + Torch, + TallGrass, + Snow, + GrassSideSnow, + Cobblestone, } impl AssetPaths for BlockTexture { fn file_name(self) -> &'static str { @@ -46,6 +47,7 @@ impl AssetPaths for BlockTexture { Self::TallGrass => "tall_grass.png", Self::Snow => "snow.png", Self::GrassSideSnow => "grass_side_snow.png", + Self::Cobblestone => "cobblestone.png", } } } diff --git a/kubi/src/world/block.rs b/kubi/src/world/block.rs index 45c2552..66a0905 100644 --- a/kubi/src/world/block.rs +++ b/kubi/src/world/block.rs @@ -41,6 +41,12 @@ impl BlockDescriptorSource for Block { collision: CollisionType::Solid, raycast_collision: true, }, + Self::Cobblestone => BlockDescriptor { + name: "cobblestone", + render: RenderType::SolidBlock(CubeTexture::all(BlockTexture::Cobblestone)), + collision: CollisionType::Solid, + raycast_collision: true, + } } } } From 102bc101e082c96422dc3ee58501bb4dc52b9e4b Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 6 Feb 2023 02:15:19 +0100 Subject: [PATCH 040/160] update --- kubi-udp/Cargo.toml | 1 + kubi-udp/src/client.rs | 24 ++++++++++++++++++++---- kubi-udp/src/common.rs | 3 ++- kubi-udp/src/lib.rs | 1 + kubi-udp/src/server.rs | 18 +++++++++++++++--- 5 files changed, 39 insertions(+), 8 deletions(-) diff --git a/kubi-udp/Cargo.toml b/kubi-udp/Cargo.toml index f99b6ad..86da226 100644 --- a/kubi-udp/Cargo.toml +++ b/kubi-udp/Cargo.toml @@ -8,5 +8,6 @@ edition = "2021" [dependencies] bincode = "2.0.0-rc" anyhow = "1.0" +hashbrown = "0.13" nohash-hasher = "0.2.0" log = "0.4" diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 8707e18..731dab0 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -3,6 +3,7 @@ use std::{ net::{UdpSocket, SocketAddr}, time::{Instant, Duration}, marker::PhantomData, + collections::{VecDeque, vec_deque::Drain}, }; use bincode::{Encode, Decode}; use crate::{ @@ -24,6 +25,12 @@ pub struct ClientConfig { pub heartbeat_interval: Duration, } +pub enum ClientEvent where T: Encode + Decode { + Connected, + Disconnected(DisconnectReason), + MessageReceived(T) +} + pub struct Client where S: Encode + Decode, R: Encode + Decode { pub config: ClientConfig, addr: SocketAddr, @@ -33,8 +40,8 @@ pub struct Client where S: Encode + Decode, R: Encode + Decode { last_heartbeat: Instant, client_id: Option, disconnect_reason: DisconnectReason, + event_queue: VecDeque>, _s: PhantomData<*const S>, - _r: PhantomData<*const R>, } impl Client where S: Encode + Decode, R: Encode + Decode { pub fn new(addr: SocketAddr, config: ClientConfig) -> Result { @@ -50,8 +57,8 @@ impl Client where S: Encode + Decode, R: Encode + Decode { last_heartbeat: Instant::now(), client_id: None, disconnect_reason: DisconnectReason::default(), + event_queue: VecDeque::new(), _s: PhantomData, - _r: PhantomData, }) } @@ -69,6 +76,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.client_id = None; self.status = ClientStatus::Disconnected; self.disconnect_reason = reason; + self.event_queue.push_back(ClientEvent::Disconnected(self.disconnect_reason.clone())); Ok(()) } @@ -105,7 +113,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { Ok(()) } - pub fn update(&mut self, callback: fn(R) -> Result<()>) -> Result<()> { + pub fn update(&mut self) -> Result<()> { // , callback: fn(ClientEvent) -> Result<()> if self.status == ClientStatus::Disconnected { return Ok(()) } @@ -137,6 +145,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { ServerPacket::Connected(client_id) => { self.client_id = Some(client_id); self.status = ClientStatus::Connected; + self.event_queue.push_back(ClientEvent::Connected); return Ok(()) }, ServerPacket::Disconnected(reason) => { @@ -146,7 +155,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { return Ok(()) }, ServerPacket::Data(message) => { - callback(message)?; + self.event_queue.push_back(ClientEvent::MessageReceived(message)); } } } else { @@ -156,4 +165,11 @@ impl Client where S: Encode + Decode, R: Encode + Decode { } Ok(()) } + + pub fn get_event(&mut self) -> Option> { + self.event_queue.pop_front() + } + pub fn process_events(&mut self) -> Drain> { + self.event_queue.drain(..) + } } diff --git a/kubi-udp/src/common.rs b/kubi-udp/src/common.rs index 83a40ef..26c56f8 100644 --- a/kubi-udp/src/common.rs +++ b/kubi-udp/src/common.rs @@ -2,8 +2,9 @@ use std::num::NonZeroU8; use bincode::{Encode, Decode}; pub type ClientId = NonZeroU8; +pub const MAX_CLIENTS: usize = u8::MAX as _; -#[derive(Default, Encode, Decode)] +#[derive(Default, Encode, Decode, Clone)] #[repr(u8)] pub enum DisconnectReason { #[default] diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs index b906e02..e4b9002 100644 --- a/kubi-udp/src/lib.rs +++ b/kubi-udp/src/lib.rs @@ -2,6 +2,7 @@ pub mod client; pub mod server; pub(crate) mod packet; pub(crate) mod common; +pub use common::{ClientId, DisconnectReason}; //pub(crate) trait Serializable: bincode::Encode + bincode::Decode {} pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 9935fc3..ff91845 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -1,14 +1,26 @@ -use std::net::{UdpSocket, SocketAddr}; -use crate::BINCODE_CONFIG; +use std::{net::{UdpSocket, SocketAddr}, time::Instant}; +use hashbrown::HashMap; +use nohash_hasher::BuildNoHashHasher; +use crate::{BINCODE_CONFIG, common::{ClientId, MAX_CLIENTS}}; + +pub struct ConnectedClient { + id: ClientId, + addr: SocketAddr, + timeout: Instant, +} pub struct Server { socket: UdpSocket, + clients: HashMap> } impl Server { pub fn bind(addr: SocketAddr) -> anyhow::Result { let socket = UdpSocket::bind(addr)?; socket.set_nonblocking(true)?; socket.set_broadcast(true)?; - Ok(Self { socket }) + Ok(Self { + socket, + clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()) + }) } } From 324dc5d43e02b128b36cb64897c3bce213d0f188 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 6 Feb 2023 02:40:45 +0100 Subject: [PATCH 041/160] ... --- kubi-udp/src/client.rs | 4 ++-- kubi-udp/src/server.rs | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 731dab0..33575ad 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -3,7 +3,7 @@ use std::{ net::{UdpSocket, SocketAddr}, time::{Instant, Duration}, marker::PhantomData, - collections::{VecDeque, vec_deque::Drain}, + collections::VecDeque, }; use bincode::{Encode, Decode}; use crate::{ @@ -169,7 +169,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { pub fn get_event(&mut self) -> Option> { self.event_queue.pop_front() } - pub fn process_events(&mut self) -> Drain> { + pub fn process_events(&mut self) -> impl Iterator> + '_ { self.event_queue.drain(..) } } diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index ff91845..a6a1a1d 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -23,4 +23,10 @@ impl Server { clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()) }) } + pub fn update(&mut self) { + let mut buf = Vec::new(); + if self.socket.recv(&mut buf).is_ok() { + todo!() + } + } } From b940a9d9d6b4221161edc6cf0097282e44c3848b Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 6 Feb 2023 02:41:34 +0100 Subject: [PATCH 042/160] disable broadcasting --- kubi-udp/src/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index a6a1a1d..3aead64 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -17,7 +17,7 @@ impl Server { pub fn bind(addr: SocketAddr) -> anyhow::Result { let socket = UdpSocket::bind(addr)?; socket.set_nonblocking(true)?; - socket.set_broadcast(true)?; + //socket.set_broadcast(true)?; Ok(Self { socket, clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()) From 4cece2a87656dbef5730c606f4ea6ff54ebc3e8a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 6 Feb 2023 03:48:43 +0100 Subject: [PATCH 043/160] wip server --- kubi-udp/src/server.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 3aead64..87c7bc8 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -9,20 +9,48 @@ pub struct ConnectedClient { timeout: Instant, } +#[derive(Clone, Copy, Debug)] +pub struct ServerConfig { + pub max_clients: usize, +} +impl Default for ServerConfig { + fn default() -> Self { + Self { + max_clients: MAX_CLIENTS, + } + } +} + pub struct Server { socket: UdpSocket, - clients: HashMap> + clients: HashMap>, + config: ServerConfig, } impl Server { - pub fn bind(addr: SocketAddr) -> anyhow::Result { + pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result { + assert!(config.max_clients <= MAX_CLIENTS); let socket = UdpSocket::bind(addr)?; socket.set_nonblocking(true)?; //socket.set_broadcast(true)?; Ok(Self { + config, socket, clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()) }) } + /// Returns None if there are no free spots left + fn connect_client(&mut self) -> Option { + let id = (1..=self.config.max_clients) + .map(|x| ClientId::new(x as _).unwrap()) + .find(|i| self.clients.contains_key(i))?; + self.clients.insert(id, ConnectedClient { + id, + addr: "0.0.0.0:0".parse().unwrap(), + timeout: Instant::now(), + }); + todo!(); + Some(id) + } pub fn update(&mut self) { let mut buf = Vec::new(); if self.socket.recv(&mut buf).is_ok() { From d5efff860c8be38fc0770948da2c74c3d93383f7 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 6 Feb 2023 19:19:02 +0100 Subject: [PATCH 044/160] wip --- kubi-udp/src/client.rs | 15 +++++++++++++-- kubi-udp/src/common.rs | 12 ------------ kubi-udp/src/lib.rs | 2 +- kubi-udp/src/server.rs | 19 ++++++++++++------- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 33575ad..91c2222 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -9,9 +9,20 @@ use bincode::{Encode, Decode}; use crate::{ BINCODE_CONFIG, packet::{ClientPacket, IdClientPacket, IdServerPacket, ServerPacket}, - common::{ClientId, DisconnectReason} + common::ClientId }; +#[derive(Default, Clone)] +#[repr(u8)] +pub enum DisconnectReason { + #[default] + NotConnected, + ClientDisconnected, + KickedByServer(Option), + ClientTimeout, + ServerTimeout, +} + #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ClientStatus { Disconnected, @@ -149,7 +160,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { return Ok(()) }, ServerPacket::Disconnected(reason) => { - let reason = DisconnectReason::KickedByServer(reason); + let reason = DisconnectReason::KickedByServer(Some(reason)); //this should never fail but we're handling the error anyway self.disconnect_inner(reason, true)?; return Ok(()) diff --git a/kubi-udp/src/common.rs b/kubi-udp/src/common.rs index 26c56f8..20e5a1e 100644 --- a/kubi-udp/src/common.rs +++ b/kubi-udp/src/common.rs @@ -1,16 +1,4 @@ use std::num::NonZeroU8; -use bincode::{Encode, Decode}; pub type ClientId = NonZeroU8; pub const MAX_CLIENTS: usize = u8::MAX as _; - -#[derive(Default, Encode, Decode, Clone)] -#[repr(u8)] -pub enum DisconnectReason { - #[default] - NotConnected, - ClientDisconnected, - KickedByServer(String), - ClientTimeout, - ServerTimeout, -} diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs index e4b9002..ec14b35 100644 --- a/kubi-udp/src/lib.rs +++ b/kubi-udp/src/lib.rs @@ -2,7 +2,7 @@ pub mod client; pub mod server; pub(crate) mod packet; pub(crate) mod common; -pub use common::{ClientId, DisconnectReason}; +pub use common::ClientId; //pub(crate) trait Serializable: bincode::Encode + bincode::Decode {} pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 87c7bc8..3edb8c2 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -1,4 +1,5 @@ use std::{net::{UdpSocket, SocketAddr}, time::Instant}; +use anyhow::{Result, bail}; use hashbrown::HashMap; use nohash_hasher::BuildNoHashHasher; use crate::{BINCODE_CONFIG, common::{ClientId, MAX_CLIENTS}}; @@ -38,18 +39,22 @@ impl Server { clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()) }) } - /// Returns None if there are no free spots left - fn connect_client(&mut self) -> Option { - let id = (1..=self.config.max_clients) + fn connect_client(&mut self, addr: SocketAddr) -> Result { + let Some(id) = (1..=self.config.max_clients) .map(|x| ClientId::new(x as _).unwrap()) - .find(|i| self.clients.contains_key(i))?; + .find(|i| self.clients.contains_key(i)) else { + bail!("Server full"); + }; + if self.clients.iter().any(|x| x.1.addr == addr) { + bail!("Already connected from the same address"); + } self.clients.insert(id, ConnectedClient { id, - addr: "0.0.0.0:0".parse().unwrap(), + addr, timeout: Instant::now(), }); - todo!(); - Some(id) + log::info!("Client with id {id} connected"); + Ok(id) } pub fn update(&mut self) { let mut buf = Vec::new(); From 44088f76e5a5aa92e771ec2bc5e43ce46c1e3cd1 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 6 Feb 2023 19:30:26 +0100 Subject: [PATCH 045/160] serializable trait --- kubi-udp/src/lib.rs | 1 + kubi-udp/src/serializable.rs | 22 ++++++++++++++++++++++ kubi-udp/src/server.rs | 2 +- 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 kubi-udp/src/serializable.rs diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs index ec14b35..319ed4f 100644 --- a/kubi-udp/src/lib.rs +++ b/kubi-udp/src/lib.rs @@ -2,6 +2,7 @@ pub mod client; pub mod server; pub(crate) mod packet; pub(crate) mod common; +pub(crate) mod serializable; pub use common::ClientId; //pub(crate) trait Serializable: bincode::Encode + bincode::Decode {} diff --git a/kubi-udp/src/serializable.rs b/kubi-udp/src/serializable.rs new file mode 100644 index 0000000..61da4d8 --- /dev/null +++ b/kubi-udp/src/serializable.rs @@ -0,0 +1,22 @@ +use anyhow::Result; +use crate::BINCODE_CONFIG; + +pub trait Serializable: bincode::Encode + bincode::Decode { + fn serialize(&self, buf: &mut [u8]) -> Result<()>; + fn deserialize(buf: &[u8]) -> Result; + + fn serialize_to_vec(&self) -> Result> { + let mut buf = Vec::new(); + self.serialize(&mut buf)?; + Ok(buf) + } +} +impl Serializable for T { + fn serialize(&self, buf: &mut [u8]) -> Result<()> { + bincode::encode_into_slice(self, buf, BINCODE_CONFIG)?; + Ok(()) + } + fn deserialize(buf: &[u8]) -> Result { + bincode::decode_from_slice(buf, BINCODE_CONFIG)?.0 + } +} diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 3edb8c2..fce125d 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -39,7 +39,7 @@ impl Server { clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()) }) } - fn connect_client(&mut self, addr: SocketAddr) -> Result { + fn add_client(&mut self, addr: SocketAddr) -> Result { let Some(id) = (1..=self.config.max_clients) .map(|x| ClientId::new(x as _).unwrap()) .find(|i| self.clients.contains_key(i)) else { From dc06305956104045975d6547d5dea9a54720ea73 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 6 Feb 2023 20:18:16 +0100 Subject: [PATCH 046/160] undo --- kubi-udp/src/lib.rs | 1 - kubi-udp/src/serializable.rs | 22 ---------------------- 2 files changed, 23 deletions(-) delete mode 100644 kubi-udp/src/serializable.rs diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs index 319ed4f..ec14b35 100644 --- a/kubi-udp/src/lib.rs +++ b/kubi-udp/src/lib.rs @@ -2,7 +2,6 @@ pub mod client; pub mod server; pub(crate) mod packet; pub(crate) mod common; -pub(crate) mod serializable; pub use common::ClientId; //pub(crate) trait Serializable: bincode::Encode + bincode::Decode {} diff --git a/kubi-udp/src/serializable.rs b/kubi-udp/src/serializable.rs deleted file mode 100644 index 61da4d8..0000000 --- a/kubi-udp/src/serializable.rs +++ /dev/null @@ -1,22 +0,0 @@ -use anyhow::Result; -use crate::BINCODE_CONFIG; - -pub trait Serializable: bincode::Encode + bincode::Decode { - fn serialize(&self, buf: &mut [u8]) -> Result<()>; - fn deserialize(buf: &[u8]) -> Result; - - fn serialize_to_vec(&self) -> Result> { - let mut buf = Vec::new(); - self.serialize(&mut buf)?; - Ok(buf) - } -} -impl Serializable for T { - fn serialize(&self, buf: &mut [u8]) -> Result<()> { - bincode::encode_into_slice(self, buf, BINCODE_CONFIG)?; - Ok(()) - } - fn deserialize(buf: &[u8]) -> Result { - bincode::decode_from_slice(buf, BINCODE_CONFIG)?.0 - } -} From aa4b552e0fcb7599b03df25b7365fa11afc61709 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 6 Feb 2023 20:54:30 +0100 Subject: [PATCH 047/160] server recv --- kubi-udp/src/server.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index fce125d..fe78696 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -58,8 +58,14 @@ impl Server { } pub fn update(&mut self) { let mut buf = Vec::new(); - if self.socket.recv(&mut buf).is_ok() { - todo!() + loop { + if self.socket.recv(&mut buf).is_ok() { + todo!() + } else { + break + } + buf.clear() } + } } From 1df8c8933015457656c8263a44c6f224e63fb97c Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 6 Feb 2023 21:43:22 +0100 Subject: [PATCH 048/160] wip things --- kubi/shaders/world.frag | 4 ++++ kubi/src/gui.rs | 1 + kubi/src/gui/text_widget.rs | 0 kubi/src/main.rs | 2 ++ kubi/src/state.rs | 14 ++++++++++++++ 5 files changed, 21 insertions(+) create mode 100644 kubi/src/gui.rs create mode 100644 kubi/src/gui/text_widget.rs create mode 100644 kubi/src/state.rs diff --git a/kubi/shaders/world.frag b/kubi/shaders/world.frag index e07b5e1..566efaf 100644 --- a/kubi/shaders/world.frag +++ b/kubi/shaders/world.frag @@ -9,6 +9,10 @@ uniform sampler2DArray tex; void main() { // base color from texture color = texture(tex, vec3(v_uv, v_tex_index)); + // discard fully transparent pixels + if (color.w <= 0.0) { + discard; + } //basic "lighting" float light = abs(v_normal.x) + .8 * abs(v_normal.y) + .6 * abs(v_normal.z); color *= vec4(vec3(light), 1.); diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs new file mode 100644 index 0000000..8ad1dfb --- /dev/null +++ b/kubi/src/gui.rs @@ -0,0 +1 @@ +//TODO diff --git a/kubi/src/gui/text_widget.rs b/kubi/src/gui/text_widget.rs new file mode 100644 index 0000000..e69de29 diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 6af453e..5acfab8 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -31,6 +31,8 @@ pub(crate) mod block_placement; pub(crate) mod delta_time; pub(crate) mod cursor_lock; pub(crate) mod control_flow; +pub(crate) mod state; +pub(crate) mod gui; use world::{ init_game_world, diff --git a/kubi/src/state.rs b/kubi/src/state.rs new file mode 100644 index 0000000..642ea78 --- /dev/null +++ b/kubi/src/state.rs @@ -0,0 +1,14 @@ +use shipyard::Unique; + +#[derive(Unique)] +pub enum GameState { + Connecting, + LoadingWorld, + InGame, +} + +fn insert_default_state( + +) { + +} From e96ae90b1d7a1b74b7dfe404e6fffc402692eb6a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Feb 2023 01:55:50 +0100 Subject: [PATCH 049/160] serveeeeer --- kubi-udp/src/server.rs | 151 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 133 insertions(+), 18 deletions(-) diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index fe78696..1a0b537 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -1,8 +1,20 @@ -use std::{net::{UdpSocket, SocketAddr}, time::Instant}; +use std::{ + net::{UdpSocket, SocketAddr}, + time::Instant, + marker::PhantomData, + collections::VecDeque +}; use anyhow::{Result, bail}; +use bincode::{Encode, Decode}; use hashbrown::HashMap; use nohash_hasher::BuildNoHashHasher; -use crate::{BINCODE_CONFIG, common::{ClientId, MAX_CLIENTS}}; +use crate::{ + BINCODE_CONFIG, + common::{ClientId, MAX_CLIENTS}, + packet::{IdClientPacket, ClientPacket, ServerPacket, IdServerPacket} +}; + +//i was feeling a bit sick while writing most of this please excuse me for my terrible code :3 pub struct ConnectedClient { id: ClientId, @@ -22,22 +34,37 @@ impl Default for ServerConfig { } } -pub struct Server { +pub enum ServerEvent where T: Encode + Decode { + Connected(ClientId), + Disconnected(ClientId), + MessageReceived { + from: ClientId, + message: T + } +} + +pub struct Server where S: Encode + Decode, R: Encode + Decode { socket: UdpSocket, clients: HashMap>, config: ServerConfig, + event_queue: VecDeque>, + _s: PhantomData<*const S>, } -impl Server { - pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result { - assert!(config.max_clients <= MAX_CLIENTS); - let socket = UdpSocket::bind(addr)?; - socket.set_nonblocking(true)?; - //socket.set_broadcast(true)?; - Ok(Self { - config, - socket, - clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()) - }) +impl Server where S: Encode + Decode, R: Encode + Decode { + fn send_to_addr(&self, addr: SocketAddr, packet: IdServerPacket) -> Result<()> { + let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; + self.socket.send_to(&bytes, addr)?; + Ok(()) + } + fn send_packet(&self, packet: IdServerPacket) -> Result<()> { + let Some(id) = packet.0 else { + bail!("send_to_client call without id") + }; + let Some(client) = self.clients.get(&id) else { + bail!("client with id {id} doesn't exist") + }; + self.send_to_addr(client.addr, packet)?; + Ok(()) } fn add_client(&mut self, addr: SocketAddr) -> Result { let Some(id) = (1..=self.config.max_clients) @@ -56,16 +83,104 @@ impl Server { log::info!("Client with id {id} connected"); Ok(id) } - pub fn update(&mut self) { + fn disconnect_client_inner(&mut self, id: ClientId, reason: String) -> Result<()> { + let result = self.send_packet(IdServerPacket( + Some(id), ServerPacket::Disconnected(reason) + )); + self.clients.remove(&id); + result + } + + pub fn kick_client(&mut self, id: ClientId, reason: String) -> Result<()> { + if !self.clients.contains_key(&id) { + bail!("Already disconnected") + } + self.disconnect_client_inner(id, reason)?; + Ok(()) + } + pub fn shutdown(mut self) -> Result<()> { + let clients = self.clients.keys().copied().collect::>(); + for id in clients { + self.kick_client(id, "Server is shutting down".into())?; + } + Ok(()) + } + pub fn send_message(&mut self) { + + } + pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result { + assert!(config.max_clients <= MAX_CLIENTS); + let socket = UdpSocket::bind(addr)?; + socket.set_nonblocking(true)?; + //socket.set_broadcast(true)?; + Ok(Self { + config, + socket, + clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()), + event_queue: VecDeque::new(), + _s: PhantomData, + }) + } + pub fn update(&mut self) -> Result<()> { + //TODO client timeout let mut buf = Vec::new(); loop { - if self.socket.recv(&mut buf).is_ok() { - todo!() + if let Ok((_, addr)) = self.socket.recv_from(&mut buf) { + if let Ok(packet) = bincode::decode_from_slice(&buf, BINCODE_CONFIG) { + let (packet, _): (IdClientPacket, _) = packet; + let IdClientPacket(id, packet) = packet; + match id { + Some(id) => { + if !self.clients.contains_key(&id) { + bail!("Client with id {id} doesn't exist"); + }; + match packet { + ClientPacket::Data(data) => { + self.event_queue.push_back(ServerEvent::MessageReceived { + from: id, + message: data, + }); + } + ClientPacket::Disconnect => { + self.event_queue.push_back(ServerEvent::Disconnected(id)); + self.disconnect_client_inner(id, "Disconnected".into())?; + }, + ClientPacket::Heartbeat => { + self.clients.get_mut(&id).unwrap().timeout = Instant::now() + }, + ClientPacket::Connect => bail!("Client already connected"), + } + }, + None => { + match packet { + ClientPacket::Connect => { + match self.add_client(addr) { + Ok(id) => { + self.event_queue.push_back(ServerEvent::Connected(id)); + self.send_to_addr(addr, + IdServerPacket(None, ServerPacket::Connected(id) + ))?; + }, + Err(error) => { + let reason = error.to_string(); + self.send_to_addr(addr, IdServerPacket( + None, ServerPacket::Disconnected(reason) + ))?; + } + } + }, + _ => bail!("Invalid packet type for non-id packet") + } + } + } + } else { + bail!("Corrupted packet received"); + } } else { break } buf.clear() } - + Ok(()) } } From f88e2733f3c2a69cb4653beba41791d42d02db9f Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Feb 2023 02:29:29 +0100 Subject: [PATCH 050/160] wip --- kubi-server/Cargo.toml | 1 + kubi-shared/src/networking/messages.rs | 10 ++-------- kubi/Cargo.toml | 1 + kubi/src/init.rs | 22 ++++++++++++++++++++++ kubi/src/main.rs | 10 +++++++--- kubi/src/networking.rs | 12 ++++++++++++ kubi/src/state.rs | 12 ++++-------- 7 files changed, 49 insertions(+), 19 deletions(-) create mode 100644 kubi/src/init.rs create mode 100644 kubi/src/networking.rs diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index efed5a4..5dc3fc5 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -5,3 +5,4 @@ edition = "2021" [dependencies] kubi-shared = { path = "../kubi-shared" } +kubi-udp = { path = "../kubi-udp" } diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index 2e2609b..9a84abf 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -12,24 +12,18 @@ pub enum ClientToServerMessage { password: Option, }, PositionChanged { - client_id: u8, - secret: u32, position: Vec3Arr, + velocity: Vec3Arr, direction: QuatArr, }, ChunkRequest { - client_id: u8, - secret: u32, chunk: IVec3Arr, }, } #[derive(Encode, Decode)] pub enum ServerToClientMessage { - ServerHello { - client_id: u8, - secret: u32, - }, + ServerHello, ServerFuckOff { reason: String, }, diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 099fa92..ace8bc5 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] kubi-shared = { path = "../kubi-shared" } +kubi-udp = { path = "../kubi-udp", optional = true } glium = "0.32" glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } image = { version = "0.24", default_features = false, features = ["png"] } diff --git a/kubi/src/init.rs b/kubi/src/init.rs new file mode 100644 index 0000000..4f96843 --- /dev/null +++ b/kubi/src/init.rs @@ -0,0 +1,22 @@ +use std::net::SocketAddr; +use shipyard::AllStoragesView; +use std::env; +use crate::{ + networking::{GameType, ServerAddress}, + state::GameState +}; + +pub fn initialize_from_args( + all_storages: AllStoragesView, +) { + let args: Vec = env::args().collect(); + if args.len() > 1 { + let address = args[1].parse::().expect("invalid address"); + all_storages.add_unique(GameType::Muliplayer); + all_storages.add_unique(GameState::Connecting); + all_storages.add_unique(ServerAddress(address)); + } else { + all_storages.add_unique(GameType::Singleplayer); + all_storages.add_unique(GameState::LoadingWorld); + } +} diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 5acfab8..cdf9bca 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -13,10 +13,10 @@ use glium::{ } }; use glam::vec3; +use state::GameState; use std::time::Instant; mod logging; - pub(crate) mod rendering; pub(crate) mod world; pub(crate) mod player; @@ -33,6 +33,8 @@ pub(crate) mod cursor_lock; pub(crate) mod control_flow; pub(crate) mod state; pub(crate) mod gui; +pub(crate) mod networking; +pub(crate) mod init; use world::{ init_game_world, @@ -63,6 +65,7 @@ use block_placement::block_placement_system; use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; +use init::initialize_from_args; fn startup() -> Workload { ( @@ -70,6 +73,7 @@ fn startup() -> Workload { load_prefabs, init_simple_box_buffers, insert_lock_state, + initialize_from_args, lock_cursor_now, init_input, init_game_world, @@ -151,9 +155,9 @@ fn main() { last_update = now; } - //Run update workflow + //Run update workflows world.run_workload(update).unwrap(); - + //Start rendering (maybe use custom views for this?) let target = { let renderer = world.borrow::>>().unwrap(); diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs new file mode 100644 index 0000000..3a3bea4 --- /dev/null +++ b/kubi/src/networking.rs @@ -0,0 +1,12 @@ +use std::net::SocketAddr; + +use shipyard::Unique; + +#[derive(Unique, Clone, Copy, PartialEq, Eq)] +pub enum GameType { + Singleplayer, + Muliplayer +} + +#[derive(Unique, Clone, Copy, PartialEq, Eq)] +pub struct ServerAddress(pub SocketAddr); diff --git a/kubi/src/state.rs b/kubi/src/state.rs index 642ea78..9319256 100644 --- a/kubi/src/state.rs +++ b/kubi/src/state.rs @@ -1,14 +1,10 @@ +use strum::EnumIter; use shipyard::Unique; -#[derive(Unique)] +#[derive(Unique, EnumIter)] +#[track(All)] pub enum GameState { Connecting, LoadingWorld, - InGame, -} - -fn insert_default_state( - -) { - + InGame } From 1ae34def217118ea6a8d3cda709d95faf5ca6c5a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Feb 2023 03:06:06 +0100 Subject: [PATCH 051/160] changed a lot of stuff, too lazy to write --- kubi/src/main.rs | 37 +++++++++++++++++++++++-------------- kubi/src/state.rs | 23 ++++++++++++++++++++--- kubi/src/world/chunk.rs | 12 ++++++++++++ kubi/src/world/loading.rs | 19 ++++++++++++++++--- 4 files changed, 71 insertions(+), 20 deletions(-) diff --git a/kubi/src/main.rs b/kubi/src/main.rs index cdf9bca..14772f3 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -4,7 +4,7 @@ use shipyard::{ World, Workload, IntoWorkload, UniqueView, UniqueViewMut, - NonSendSync + NonSendSync, WorkloadModificator }; use glium::{ glutin::{ @@ -13,7 +13,6 @@ use glium::{ } }; use glam::vec3; -use state::GameState; use std::time::Instant; mod logging; @@ -38,7 +37,7 @@ pub(crate) mod init; use world::{ init_game_world, - loading::update_loaded_world_around_player, + loading::{update_loaded_world_around_player, switch_to_ingame_if_loaded}, raycast::update_raycasts, queue::apply_queued_blocks }; use player::spawn_player; @@ -65,6 +64,7 @@ use block_placement::block_placement_system; use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; +use state::{GameState, is_ingame, is_ingame_or_loading, is_loading}; use init::initialize_from_args; fn startup() -> Workload { @@ -84,24 +84,33 @@ fn startup() -> Workload { } fn update() -> Workload { ( - process_inputs, - update_controllers, - generate_move_events, - update_loaded_world_around_player, - update_raycasts, - block_placement_system, - apply_queued_blocks, update_cursor_lock_state, - compute_cameras, + process_inputs, exit_on_esc, + ( + switch_to_ingame_if_loaded, + ).into_workload().run_if(is_loading), + ( + update_loaded_world_around_player, + ).into_workload().run_if(is_ingame_or_loading), + ( + update_controllers, + generate_move_events, + update_raycasts, + block_placement_system, + apply_queued_blocks, + ).into_workload().run_if(is_ingame), + compute_cameras, ).into_workload() } fn render() -> Workload { ( clear_background, - draw_world, - draw_current_chunk_border, - render_selection_box, + ( + draw_world, + draw_current_chunk_border, + render_selection_box, + ).into_sequential_workload().run_if(is_ingame) ).into_sequential_workload() } fn after_frame_end() -> Workload { diff --git a/kubi/src/state.rs b/kubi/src/state.rs index 9319256..1f1297f 100644 --- a/kubi/src/state.rs +++ b/kubi/src/state.rs @@ -1,10 +1,27 @@ -use strum::EnumIter; -use shipyard::Unique; +use shipyard::{Unique, UniqueView}; -#[derive(Unique, EnumIter)] +#[derive(Unique, PartialEq, Eq)] #[track(All)] pub enum GameState { Connecting, LoadingWorld, InGame } + +pub fn is_ingame( + state: UniqueView +) -> bool { + *state == GameState::InGame +} + +pub fn is_loading( + state: UniqueView +) -> bool { + matches!(*state, GameState::LoadingWorld) +} + +pub fn is_ingame_or_loading( + state: UniqueView +) -> bool { + matches!(*state, GameState::InGame | GameState::LoadingWorld) +} diff --git a/kubi/src/world/chunk.rs b/kubi/src/world/chunk.rs index 7d3733d..cd8f77e 100644 --- a/kubi/src/world/chunk.rs +++ b/kubi/src/world/chunk.rs @@ -30,6 +30,11 @@ pub enum CurrentChunkState { RecalculatingMesh, Unloading, } +impl CurrentChunkState { + pub fn matches(self, desired: DesiredChunkState) -> bool { + desired.matches(self) + } +} #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] pub enum DesiredChunkState { @@ -39,6 +44,13 @@ pub enum DesiredChunkState { Rendered, ToUnload, } +impl DesiredChunkState { + pub fn matches(self, current: CurrentChunkState) -> bool { + (matches!(self, DesiredChunkState::Nothing) && matches!(current, CurrentChunkState::Nothing)) || + (matches!(self, DesiredChunkState::Loaded) && matches!(current, CurrentChunkState::Loaded)) || + (matches!(self, DesiredChunkState::Rendered) && matches!(current, CurrentChunkState::Rendered)) + } +} pub struct Chunk { pub position: IVec3, diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index a248857..2254009 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -5,7 +5,8 @@ use crate::{ player::MainPlayer, transform::Transform, settings::GameSettings, - rendering::Renderer + rendering::Renderer, + state::GameState }; use super::{ ChunkStorage, ChunkMeshStorage, @@ -168,7 +169,8 @@ fn process_completed_tasks( task_manager: UniqueView, mut world: UniqueViewMut, mut meshes: NonSendSync>, - renderer: NonSendSync> + renderer: NonSendSync>, + state: UniqueView ) { let mut ops: usize = 0; while let Some(res) = task_manager.receive() { @@ -231,8 +233,19 @@ fn process_completed_tasks( ops += 1; } } - if ops >= MAX_CHUNK_OPS { + if (ops >= MAX_CHUNK_OPS) && matches!(*state, GameState::InGame) { break } } } + +pub fn switch_to_ingame_if_loaded( + world: UniqueView, + mut state: UniqueViewMut +) { + if world.chunks.iter().all(|(_, chunk)| { + chunk.desired_state.matches(chunk.current_state) + }) { + *state = GameState::InGame; + } +} From fb8aa9d5285453d192fb2d45c7ce3e3748a8f49c Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Feb 2023 03:09:04 +0100 Subject: [PATCH 052/160] fix --- kubi/src/world/loading.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index 2254009..307b898 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -243,6 +243,9 @@ pub fn switch_to_ingame_if_loaded( world: UniqueView, mut state: UniqueViewMut ) { + if world.chunks.is_empty() { + return + } if world.chunks.iter().all(|(_, chunk)| { chunk.desired_state.matches(chunk.current_state) }) { From a6a728ba1004b1805faa92de61c1810e157e9eea Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Feb 2023 03:10:35 +0100 Subject: [PATCH 053/160] gui files --- kubi/src/gui.rs | 2 ++ kubi/src/gui/progressbar.rs | 0 2 files changed, 2 insertions(+) create mode 100644 kubi/src/gui/progressbar.rs diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index 8ad1dfb..68f99b2 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -1 +1,3 @@ //TODO +pub mod text_widget; +pub mod progressbar; diff --git a/kubi/src/gui/progressbar.rs b/kubi/src/gui/progressbar.rs new file mode 100644 index 0000000..e69de29 From 9f2e47df8cd71d6ca6a793af198efb035c347a76 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Feb 2023 03:37:58 +0100 Subject: [PATCH 054/160] shaders for progressbar --- kubi/shaders/gui/progress.frag | 15 +++++++++++++++ kubi/shaders/gui/progress.vert | 13 +++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 kubi/shaders/gui/progress.frag create mode 100644 kubi/shaders/gui/progress.vert diff --git a/kubi/shaders/gui/progress.frag b/kubi/shaders/gui/progress.frag new file mode 100644 index 0000000..1474e79 --- /dev/null +++ b/kubi/shaders/gui/progress.frag @@ -0,0 +1,15 @@ +#version 150 core + +in vec2 v_uv; +out vec4 out_color; +uniform float progress; +uniform vec4 color; +uniform vec4 bg_color; + +void main() { + if (v_uv.x <= progress) { + out_color = color; + } else { + out_color = bg_color; + } +} diff --git a/kubi/shaders/gui/progress.vert b/kubi/shaders/gui/progress.vert new file mode 100644 index 0000000..82ad5d7 --- /dev/null +++ b/kubi/shaders/gui/progress.vert @@ -0,0 +1,13 @@ +#version 150 core + +in vec2 position; +in vec2 uv; +out vec2 v_uv; +uniform vec2 ui_scale; +uniform vec2 element_position; +uniform vec2 element_size; + +void main() { + v_uv = uv; + gl_Position = vec4(ui_scale * (element_position + (position * element_size)), 0.0, 1.0); +} From 8ed0765c9f70e5141cd2ffaf0834a5436ec581fe Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 9 Feb 2023 03:31:36 +0100 Subject: [PATCH 055/160] gui and progressbars --- Cargo.toml | 4 + kubi/shaders/gui/progress.vert | 13 --- .../gui/{progress.frag => progressbar.frag} | 0 kubi/shaders/gui/progressbar.vert | 12 +++ kubi/src/block_placement.rs | 2 +- kubi/src/color.rs | 12 +++ kubi/src/gui.rs | 74 +++++++++++++++- kubi/src/gui/progressbar.rs | 47 ++++++++++ kubi/src/gui/text_widget.rs | 1 + kubi/src/main.rs | 16 ++-- kubi/src/prefabs.rs | 15 +++- kubi/src/rendering/primitives.rs | 85 ++++--------------- kubi/src/rendering/primitives/cube.rs | 56 ++++++++++++ kubi/src/rendering/primitives/rect.rs | 31 +++++++ kubi/src/rendering/selection_box.rs | 4 +- kubi/src/rendering/world.rs | 8 +- kubi/src/transform.rs | 2 +- 17 files changed, 284 insertions(+), 98 deletions(-) delete mode 100644 kubi/shaders/gui/progress.vert rename kubi/shaders/gui/{progress.frag => progressbar.frag} (100%) create mode 100644 kubi/shaders/gui/progressbar.vert create mode 100644 kubi/src/color.rs create mode 100644 kubi/src/rendering/primitives/cube.rs create mode 100644 kubi/src/rendering/primitives/rect.rs diff --git a/Cargo.toml b/Cargo.toml index c0cf813..de197ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,10 @@ members = ["kubi", "kubi-server", "kubi-shared", "kubi-udp"] resolver = "2" +[profile.release-with-debug] +inherits = "release" +debug = true + [profile.dev] opt-level = 1 diff --git a/kubi/shaders/gui/progress.vert b/kubi/shaders/gui/progress.vert deleted file mode 100644 index 82ad5d7..0000000 --- a/kubi/shaders/gui/progress.vert +++ /dev/null @@ -1,13 +0,0 @@ -#version 150 core - -in vec2 position; -in vec2 uv; -out vec2 v_uv; -uniform vec2 ui_scale; -uniform vec2 element_position; -uniform vec2 element_size; - -void main() { - v_uv = uv; - gl_Position = vec4(ui_scale * (element_position + (position * element_size)), 0.0, 1.0); -} diff --git a/kubi/shaders/gui/progress.frag b/kubi/shaders/gui/progressbar.frag similarity index 100% rename from kubi/shaders/gui/progress.frag rename to kubi/shaders/gui/progressbar.frag diff --git a/kubi/shaders/gui/progressbar.vert b/kubi/shaders/gui/progressbar.vert new file mode 100644 index 0000000..d57292c --- /dev/null +++ b/kubi/shaders/gui/progressbar.vert @@ -0,0 +1,12 @@ +#version 150 core + +in vec2 position; +out vec2 uv; +uniform vec2 ui_view; +uniform vec2 element_position; +uniform vec2 element_size; + +void main() { + uv = position; + gl_Position = vec4(ui_view * (element_position + (position * element_size)), 0.0, 1.0); +} diff --git a/kubi/src/block_placement.rs b/kubi/src/block_placement.rs index 3eff4be..a0f3991 100644 --- a/kubi/src/block_placement.rs +++ b/kubi/src/block_placement.rs @@ -1,7 +1,7 @@ use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut}; use crate::{ player::MainPlayer, - world::{raycast::LookingAtBlock, ChunkStorage, block::Block, queue::{BlockUpdateQueue, BlockUpdateEvent}}, + world::{raycast::LookingAtBlock, block::Block, queue::{BlockUpdateQueue, BlockUpdateEvent}}, input::{Inputs, PrevInputs}, events::{EventComponent, player_actions::PlayerActionEvent}, }; diff --git a/kubi/src/color.rs b/kubi/src/color.rs new file mode 100644 index 0000000..1854ff4 --- /dev/null +++ b/kubi/src/color.rs @@ -0,0 +1,12 @@ +use glam::{Vec4, vec4}; + +#[inline(always)] +pub fn color_rgba(r: u8, g: u8, b: u8, a: u8) -> Vec4 { + vec4(r as f32 / 255., g as f32 / 255., b as f32 / 255., a as f32 / 255.) +} + +#[inline(always)] +pub const fn color_hex(c: u32) -> Vec4 { + let c = c.to_le_bytes(); + vec4(c[0] as f32, c[1] as f32, c[2] as f32, c[3] as f32) +} diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index 68f99b2..2230e2b 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -1,3 +1,75 @@ -//TODO +use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, AllStoragesViewMut}; +use glam::{Vec2, Vec4, vec2}; +use crate::color::color_hex; + pub mod text_widget; pub mod progressbar; + +use progressbar::{render_progressbars, ProgressbarComponent}; + +//TODO compute gui scale on window resize +#[derive(Unique, Clone, Copy, Debug)] +pub struct GuiViewScale(pub Vec2); + +#[derive(Component, Clone, Copy, Debug, Default)] +pub struct GuiComponent; + +#[derive(Component, Clone, Copy, Debug)] +#[track(All)] +pub struct GuiTransform { + pub position: Vec2, + pub scale: Vec2, +} +impl Default for GuiTransform { + fn default() -> Self { + Self { + position: Vec2::ZERO, + scale: Vec2::ONE, + } + } +} + +#[derive(Component, Clone, Copy, Debug)] +pub struct PrimaryColor(pub Vec4); +impl Default for PrimaryColor { + fn default() -> Self { + Self(color_hex(0x156cdd)) + } +} + +#[derive(Component, Clone, Copy, Debug)] +pub struct SecondaryColor(pub Vec4); +impl Default for SecondaryColor { + fn default() -> Self { + Self(color_hex(0xc9d5e4)) + } +} + +pub fn render_gui() -> Workload { + ( + render_progressbars + ).into_workload() +} + +pub fn init_gui( + storages: AllStoragesView, +) { + storages.add_unique(GuiViewScale(Vec2::ONE)); +} + +pub fn gui_testing( + mut storages: AllStoragesViewMut, +) { + storages.add_entity(( + GuiComponent, + GuiTransform { + position: Vec2::ZERO, + scale: vec2(1.0, 0.05), + }, + ProgressbarComponent { + progress: 0.5 + }, + PrimaryColor::default(), + SecondaryColor::default(), + )); +} diff --git a/kubi/src/gui/progressbar.rs b/kubi/src/gui/progressbar.rs index e69de29..847c584 100644 --- a/kubi/src/gui/progressbar.rs +++ b/kubi/src/gui/progressbar.rs @@ -0,0 +1,47 @@ +use shipyard::{UniqueView, UniqueViewMut, NonSendSync, View, Component, IntoIter}; +use glium::{Surface, uniform, DrawParameters}; +use crate::{ + prefabs::ProgressbarShaderPrefab, + rendering::{ + RenderTarget, + primitives::rect::RectPrimitive + }, +}; +use super::{GuiComponent, GuiTransform, PrimaryColor, SecondaryColor, GuiViewScale}; + +#[derive(Component, Debug, Clone, Copy, Default)] +pub struct ProgressbarComponent { + pub progress: f32 +} + +pub fn render_progressbars( + mut target: NonSendSync>, + rect: NonSendSync>, + program: NonSendSync>, + view: UniqueView, + components: View, + transforms: View, + progressbars: View, + primary: View, + secondary: View, +) { + for (_, transform, progress, pri, sec) in (&components, &transforms, &progressbars, &primary, &secondary).iter() { + //TODO do this properly + let pri = Some(pri).copied(); + let sec = Some(sec).copied(); + target.0.draw( + &rect.0, + &rect.1, + &program.0, + &uniform! { + element_position: transform.position.to_array(), + element_size: transform.scale.to_array(), + ui_view: view.0.to_array(), + progress: progress.progress, + color: pri.unwrap_or_default().0.to_array(), + bg_color: sec.unwrap_or_default().0.to_array(), + }, + &DrawParameters::default() + ).unwrap(); + } +} diff --git a/kubi/src/gui/text_widget.rs b/kubi/src/gui/text_widget.rs index e69de29..31c4422 100644 --- a/kubi/src/gui/text_widget.rs +++ b/kubi/src/gui/text_widget.rs @@ -0,0 +1 @@ +//TODO text widget diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 14772f3..0440b0b 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -34,11 +34,13 @@ pub(crate) mod state; pub(crate) mod gui; pub(crate) mod networking; pub(crate) mod init; +pub(crate) mod color; use world::{ init_game_world, loading::{update_loaded_world_around_player, switch_to_ingame_if_loaded}, - raycast::update_raycasts, queue::apply_queued_blocks + raycast::update_raycasts, + queue::apply_queued_blocks }; use player::spawn_player; use prefabs::load_prefabs; @@ -55,7 +57,7 @@ use rendering::{ RenderTarget, BackgroundColor, clear_background, - primitives::init_simple_box_buffers, + primitives::init_primitives, selection_box::render_selection_box, world::draw_world, world::draw_current_chunk_border, @@ -64,18 +66,21 @@ use block_placement::block_placement_system; use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; -use state::{GameState, is_ingame, is_ingame_or_loading, is_loading}; +use state::{is_ingame, is_ingame_or_loading, is_loading}; use init::initialize_from_args; +use gui::{render_gui, init_gui, gui_testing}; fn startup() -> Workload { ( load_settings, load_prefabs, - init_simple_box_buffers, + init_primitives, insert_lock_state, initialize_from_args, lock_cursor_now, init_input, + init_gui, + gui_testing, init_game_world, spawn_player, insert_control_flow_unique, @@ -110,7 +115,8 @@ fn render() -> Workload { draw_world, draw_current_chunk_border, render_selection_box, - ).into_sequential_workload().run_if(is_ingame) + ).into_sequential_workload().run_if(is_ingame), + render_gui, ).into_sequential_workload() } fn after_frame_end() -> Workload { diff --git a/kubi/src/prefabs.rs b/kubi/src/prefabs.rs index 4529bce..6d1aa76 100644 --- a/kubi/src/prefabs.rs +++ b/kubi/src/prefabs.rs @@ -62,7 +62,10 @@ pub struct ChunkShaderPrefab(pub Program); pub struct SelBoxShaderPrefab(pub Program); #[derive(Unique)] -pub struct BasicColoredShaderPrefab(pub Program); +pub struct ColoredShaderPrefab(pub Program); + +#[derive(Unique)] +pub struct ProgressbarShaderPrefab(pub Program); pub fn load_prefabs( storages: AllStoragesView, @@ -94,7 +97,7 @@ pub fn load_prefabs( &renderer.display ) )); - storages.add_unique_non_send_sync(BasicColoredShaderPrefab( + storages.add_unique_non_send_sync(ColoredShaderPrefab( include_shader_prefab!( "colored", "../shaders/colored.vert", @@ -102,4 +105,12 @@ pub fn load_prefabs( &renderer.display ) )); + storages.add_unique_non_send_sync(ProgressbarShaderPrefab( + include_shader_prefab!( + "gui/progressbar", + "../shaders/gui/progressbar.vert", + "../shaders/gui/progressbar.frag", + &renderer.display + ) + )); } diff --git a/kubi/src/rendering/primitives.rs b/kubi/src/rendering/primitives.rs index ce05f83..6861b3e 100644 --- a/kubi/src/rendering/primitives.rs +++ b/kubi/src/rendering/primitives.rs @@ -1,39 +1,11 @@ -use glium::{implement_vertex, VertexBuffer, IndexBuffer, index::PrimitiveType}; -use shipyard::{NonSendSync, UniqueView, AllStoragesView, Unique}; -use super::Renderer; +use shipyard::{Workload, IntoWorkload}; +use glium::implement_vertex; -pub const CUBE_VERTICES: &[f32] = &[ - // front - 0.0, 0.0, 1.0, - 1.0, 0.0, 1.0, - 1.0, 1.0, 1.0, - 0.0, 1.0, 1.0, - // back - 0.0, 0.0, 0.0, - 1.0, 0.0, 0.0, - 1.0, 1.0, 0.0, - 0.0, 1.0, 0.0 -]; -pub const CUBE_INDICES: &[u16] = &[ - // front - 0, 1, 2, - 2, 3, 0, - // right - 1, 5, 6, - 6, 2, 1, - // back - 7, 6, 5, - 5, 4, 7, - // left - 4, 0, 3, - 3, 7, 4, - // bottom - 4, 5, 1, - 1, 0, 4, - // top - 3, 2, 6, - 6, 7, 3 -]; +pub mod cube; +pub mod rect; + +use cube::init_cube_primitive; +use rect::init_rect_primitive; #[derive(Clone, Copy, Default)] pub struct PositionOnlyVertex { @@ -41,40 +13,15 @@ pub struct PositionOnlyVertex { } implement_vertex!(PositionOnlyVertex, position); -const fn box_vertices() -> [PositionOnlyVertex; CUBE_VERTICES.len() / 3] { - let mut arr = [PositionOnlyVertex { position: [0., 0., 0.] }; CUBE_VERTICES.len() / 3]; - let mut ptr = 0; - loop { - arr[ptr] = PositionOnlyVertex { - position: [ - CUBE_VERTICES[ptr * 3], - CUBE_VERTICES[(ptr * 3) + 1], - CUBE_VERTICES[(ptr * 3) + 2] - ] - }; - ptr += 1; - if ptr >= CUBE_VERTICES.len() / 3 { - return arr - } - } +#[derive(Clone, Copy, Default)] +pub struct PositionOnlyVertex2d { + pub position: [f32; 2], } -const BOX_VERTICES: &[PositionOnlyVertex] = &box_vertices(); +implement_vertex!(PositionOnlyVertex2d, position); -#[derive(Unique)] -pub struct SimpleBoxBuffers(pub VertexBuffer, pub IndexBuffer); - -pub fn init_simple_box_buffers( - storages: AllStoragesView, - display: NonSendSync> -) { - let vert = VertexBuffer::new( - &display.display, - BOX_VERTICES - ).unwrap(); - let index = IndexBuffer::new( - &display.display, - PrimitiveType::TrianglesList, - CUBE_INDICES - ).unwrap(); - storages.add_unique_non_send_sync(SimpleBoxBuffers(vert, index)); +pub fn init_primitives() -> Workload { + ( + init_cube_primitive, + init_rect_primitive, + ).into_workload() } diff --git a/kubi/src/rendering/primitives/cube.rs b/kubi/src/rendering/primitives/cube.rs new file mode 100644 index 0000000..cee8f02 --- /dev/null +++ b/kubi/src/rendering/primitives/cube.rs @@ -0,0 +1,56 @@ +use shipyard::{AllStoragesView, NonSendSync, UniqueView, Unique}; +use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType}; +use crate::rendering::Renderer; +use super::PositionOnlyVertex; + +#[derive(Unique)] +pub struct CubePrimitive(pub VertexBuffer, pub IndexBuffer); + +const CUBE_VERTICES: &[PositionOnlyVertex] = &[ + // front + PositionOnlyVertex { position: [0.0, 0.0, 1.0] }, + PositionOnlyVertex { position: [1.0, 0.0, 1.0] }, + PositionOnlyVertex { position: [1.0, 1.0, 1.0] }, + PositionOnlyVertex { position: [0.0, 1.0, 1.0] }, + // back + PositionOnlyVertex { position: [0.0, 0.0, 0.0] }, + PositionOnlyVertex { position: [1.0, 0.0, 0.0] }, + PositionOnlyVertex { position: [1.0, 1.0, 0.0] }, + PositionOnlyVertex { position: [0.0, 1.0, 0.0] }, +]; +const CUBE_INDICES: &[u16] = &[ + // front + 0, 1, 2, + 2, 3, 0, + // right + 1, 5, 6, + 6, 2, 1, + // back + 7, 6, 5, + 5, 4, 7, + // left + 4, 0, 3, + 3, 7, 4, + // bottom + 4, 5, 1, + 1, 0, 4, + // top + 3, 2, 6, + 6, 7, 3 +]; + +pub(super) fn init_cube_primitive( + storages: AllStoragesView, + display: NonSendSync> +) { + let vert = VertexBuffer::new( + &display.display, + CUBE_VERTICES + ).unwrap(); + let index = IndexBuffer::new( + &display.display, + PrimitiveType::TrianglesList, + CUBE_INDICES + ).unwrap(); + storages.add_unique_non_send_sync(CubePrimitive(vert, index)); +} diff --git a/kubi/src/rendering/primitives/rect.rs b/kubi/src/rendering/primitives/rect.rs new file mode 100644 index 0000000..0215d14 --- /dev/null +++ b/kubi/src/rendering/primitives/rect.rs @@ -0,0 +1,31 @@ +use shipyard::{Unique, AllStoragesView, NonSendSync, UniqueView}; +use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType}; +use crate::rendering::Renderer; +use super::PositionOnlyVertex2d; + +#[derive(Unique)] +pub struct RectPrimitive(pub VertexBuffer, pub IndexBuffer); + +const RECT_VERTEX: &[PositionOnlyVertex2d] = &[ + PositionOnlyVertex2d { position: [0., 0.] }, + PositionOnlyVertex2d { position: [1., 0.] }, + PositionOnlyVertex2d { position: [0., 1.] }, + PositionOnlyVertex2d { position: [1., 1.] }, +]; +const RECT_INDEX: &[u16] = &[0, 1, 2, 1, 3, 2]; + +pub(super) fn init_rect_primitive( + storages: AllStoragesView, + display: NonSendSync> +) { + let vert = VertexBuffer::new( + &display.display, + RECT_VERTEX + ).unwrap(); + let index = IndexBuffer::new( + &display.display, + PrimitiveType::TrianglesList, + RECT_INDEX + ).unwrap(); + storages.add_unique_non_send_sync(RectPrimitive(vert, index)); +} diff --git a/kubi/src/rendering/selection_box.rs b/kubi/src/rendering/selection_box.rs index b04f75c..1c8cc5a 100644 --- a/kubi/src/rendering/selection_box.rs +++ b/kubi/src/rendering/selection_box.rs @@ -12,7 +12,7 @@ use crate::{ }; use super::{ RenderTarget, - primitives::SimpleBoxBuffers, + primitives::cube::CubePrimitive, }; pub fn render_selection_box( @@ -20,7 +20,7 @@ pub fn render_selection_box( camera: View, mut target: NonSendSync>, program: NonSendSync>, - buffers: NonSendSync>, + buffers: NonSendSync>, ) { let camera = camera.iter().next().unwrap(); let Some(lookat) = lookat.iter().next() else { return }; diff --git a/kubi/src/rendering/world.rs b/kubi/src/rendering/world.rs index f4770ec..a42136b 100644 --- a/kubi/src/rendering/world.rs +++ b/kubi/src/rendering/world.rs @@ -24,7 +24,7 @@ use crate::{ prefabs::{ ChunkShaderPrefab, BlockTexturesPrefab, - BasicColoredShaderPrefab, + ColoredShaderPrefab, }, world::{ ChunkStorage, @@ -32,7 +32,7 @@ use crate::{ chunk::CHUNK_SIZE, }, settings::GameSettings, }; -use super::{RenderTarget, primitives::SimpleBoxBuffers}; +use super::{RenderTarget, primitives::cube::CubePrimitive}; #[derive(Clone, Copy)] pub struct ChunkVertex { @@ -114,8 +114,8 @@ pub fn draw_current_chunk_border( mut target: NonSendSync>, player: View, transforms: View, - buffers: NonSendSync>, - program: NonSendSync>, + buffers: NonSendSync>, + program: NonSendSync>, camera: View, settings: UniqueView, ) { diff --git a/kubi/src/transform.rs b/kubi/src/transform.rs index 5087b6c..643603e 100644 --- a/kubi/src/transform.rs +++ b/kubi/src/transform.rs @@ -1,5 +1,5 @@ use shipyard::Component; -use glam::Mat4; +use glam::{Mat4, Vec2}; #[derive(Component, Clone, Copy, Debug, Default)] #[track(All)] From 6b34352c5529f8f500fd3a262580281b6aa3ce25 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 9 Feb 2023 03:33:41 +0100 Subject: [PATCH 056/160] fix color-related code --- kubi/src/color.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubi/src/color.rs b/kubi/src/color.rs index 1854ff4..6e11e3e 100644 --- a/kubi/src/color.rs +++ b/kubi/src/color.rs @@ -6,7 +6,7 @@ pub fn color_rgba(r: u8, g: u8, b: u8, a: u8) -> Vec4 { } #[inline(always)] -pub const fn color_hex(c: u32) -> Vec4 { +pub fn color_hex(c: u32) -> Vec4 { let c = c.to_le_bytes(); - vec4(c[0] as f32, c[1] as f32, c[2] as f32, c[3] as f32) + color_rgba(c[0], c[1], c[2], c[3]) } From da4a6861002695b91595e574f4e1d331b0776064 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 9 Feb 2023 03:34:49 +0100 Subject: [PATCH 057/160] fix default colors and color_hex function --- kubi/src/color.rs | 2 +- kubi/src/gui.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kubi/src/color.rs b/kubi/src/color.rs index 6e11e3e..5e0728b 100644 --- a/kubi/src/color.rs +++ b/kubi/src/color.rs @@ -7,6 +7,6 @@ pub fn color_rgba(r: u8, g: u8, b: u8, a: u8) -> Vec4 { #[inline(always)] pub fn color_hex(c: u32) -> Vec4 { - let c = c.to_le_bytes(); + let c = c.to_be_bytes(); color_rgba(c[0], c[1], c[2], c[3]) } diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index 2230e2b..ebdb0c1 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -33,7 +33,7 @@ impl Default for GuiTransform { pub struct PrimaryColor(pub Vec4); impl Default for PrimaryColor { fn default() -> Self { - Self(color_hex(0x156cdd)) + Self(color_hex(0x156cddff)) } } @@ -41,7 +41,7 @@ impl Default for PrimaryColor { pub struct SecondaryColor(pub Vec4); impl Default for SecondaryColor { fn default() -> Self { - Self(color_hex(0xc9d5e4)) + Self(color_hex(0xc9d5e4ff)) } } From e75693926ac9bdc99d8a5b027c5c16bbeae9ff14 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 9 Feb 2023 04:11:15 +0100 Subject: [PATCH 058/160] why doesnt it work --- kubi/shaders/gui/progressbar.vert | 17 ++++++++++++---- kubi/src/gui.rs | 32 +++++++++---------------------- kubi/src/gui/progressbar.rs | 13 ++++++------- kubi/src/transform.rs | 6 +++++- 4 files changed, 33 insertions(+), 35 deletions(-) diff --git a/kubi/shaders/gui/progressbar.vert b/kubi/shaders/gui/progressbar.vert index d57292c..8ae28dd 100644 --- a/kubi/shaders/gui/progressbar.vert +++ b/kubi/shaders/gui/progressbar.vert @@ -2,11 +2,20 @@ in vec2 position; out vec2 uv; -uniform vec2 ui_view; -uniform vec2 element_position; -uniform vec2 element_size; +uniform mat4 ui_view; +uniform mat3 transform; + +//not sure if mat4(i) does the same thing +mat4 extend(mat3 i) { + mat4 o; + o[0] = vec4(i[0].xyz, 0); + o[1] = vec4(i[1].xyz, 0); + o[2] = vec4(i[2].xyz, 0); + o[3] = vec4(0, 0, 0, 1); + return o; +} void main() { uv = position; - gl_Position = vec4(ui_view * (element_position + (position * element_size)), 0.0, 1.0); + gl_Position = ui_view * extend(transform) * vec4(position, 0., 1.); } diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index ebdb0c1..cbc5017 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -1,6 +1,6 @@ use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, AllStoragesViewMut}; -use glam::{Vec2, Vec4, vec2}; -use crate::color::color_hex; +use glam::{Vec2, Vec4, Mat3, vec2, Mat4}; +use crate::{color::color_hex, transform::Transform2d}; pub mod text_widget; pub mod progressbar; @@ -9,26 +9,11 @@ use progressbar::{render_progressbars, ProgressbarComponent}; //TODO compute gui scale on window resize #[derive(Unique, Clone, Copy, Debug)] -pub struct GuiViewScale(pub Vec2); +pub struct GuiView(pub Mat4); #[derive(Component, Clone, Copy, Debug, Default)] pub struct GuiComponent; -#[derive(Component, Clone, Copy, Debug)] -#[track(All)] -pub struct GuiTransform { - pub position: Vec2, - pub scale: Vec2, -} -impl Default for GuiTransform { - fn default() -> Self { - Self { - position: Vec2::ZERO, - scale: Vec2::ONE, - } - } -} - #[derive(Component, Clone, Copy, Debug)] pub struct PrimaryColor(pub Vec4); impl Default for PrimaryColor { @@ -54,7 +39,7 @@ pub fn render_gui() -> Workload { pub fn init_gui( storages: AllStoragesView, ) { - storages.add_unique(GuiViewScale(Vec2::ONE)); + storages.add_unique(GuiView(Mat4::orthographic_rh_gl(0.0, 1.0, 1.0, 0.0, 0.0, 1.0))); } pub fn gui_testing( @@ -62,10 +47,11 @@ pub fn gui_testing( ) { storages.add_entity(( GuiComponent, - GuiTransform { - position: Vec2::ZERO, - scale: vec2(1.0, 0.05), - }, + Transform2d(Mat3::from_scale_angle_translation( + vec2(0.25, 0.05), + 0., + vec2(0.5, 0.) + )), ProgressbarComponent { progress: 0.5 }, diff --git a/kubi/src/gui/progressbar.rs b/kubi/src/gui/progressbar.rs index 847c584..3e848c9 100644 --- a/kubi/src/gui/progressbar.rs +++ b/kubi/src/gui/progressbar.rs @@ -5,9 +5,9 @@ use crate::{ rendering::{ RenderTarget, primitives::rect::RectPrimitive - }, + }, transform::Transform2d, }; -use super::{GuiComponent, GuiTransform, PrimaryColor, SecondaryColor, GuiViewScale}; +use super::{GuiComponent, PrimaryColor, SecondaryColor, GuiView}; #[derive(Component, Debug, Clone, Copy, Default)] pub struct ProgressbarComponent { @@ -18,9 +18,9 @@ pub fn render_progressbars( mut target: NonSendSync>, rect: NonSendSync>, program: NonSendSync>, - view: UniqueView, + view: UniqueView, components: View, - transforms: View, + transforms: View, progressbars: View, primary: View, secondary: View, @@ -34,9 +34,8 @@ pub fn render_progressbars( &rect.1, &program.0, &uniform! { - element_position: transform.position.to_array(), - element_size: transform.scale.to_array(), - ui_view: view.0.to_array(), + transform: transform.0.to_cols_array_2d(), + ui_view: view.0.to_cols_array_2d(), progress: progress.progress, color: pri.unwrap_or_default().0.to_array(), bg_color: sec.unwrap_or_default().0.to_array(), diff --git a/kubi/src/transform.rs b/kubi/src/transform.rs index 643603e..6d38bfe 100644 --- a/kubi/src/transform.rs +++ b/kubi/src/transform.rs @@ -1,6 +1,10 @@ use shipyard::Component; -use glam::{Mat4, Vec2}; +use glam::{Mat4, Mat3}; #[derive(Component, Clone, Copy, Debug, Default)] #[track(All)] pub struct Transform(pub Mat4); + +#[derive(Component, Clone, Copy, Debug, Default)] +#[track(All)] +pub struct Transform2d(pub Mat3); From 50ef5c2d1e0574f4351e4ab1cbea95907d1cd003 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 9 Feb 2023 04:16:02 +0100 Subject: [PATCH 059/160] ui transform works --- kubi/shaders/gui/progressbar.vert | 13 ++----------- kubi/src/gui.rs | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/kubi/shaders/gui/progressbar.vert b/kubi/shaders/gui/progressbar.vert index 8ae28dd..35ca9c7 100644 --- a/kubi/shaders/gui/progressbar.vert +++ b/kubi/shaders/gui/progressbar.vert @@ -5,17 +5,8 @@ out vec2 uv; uniform mat4 ui_view; uniform mat3 transform; -//not sure if mat4(i) does the same thing -mat4 extend(mat3 i) { - mat4 o; - o[0] = vec4(i[0].xyz, 0); - o[1] = vec4(i[1].xyz, 0); - o[2] = vec4(i[2].xyz, 0); - o[3] = vec4(0, 0, 0, 1); - return o; -} - void main() { uv = position; - gl_Position = ui_view * extend(transform) * vec4(position, 0., 1.); + vec2 transformed = (transform * vec3(position, 1.)).xy; + gl_Position = ui_view * vec4(transformed, 0., 1.); } diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index cbc5017..41069ba 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -50,7 +50,7 @@ pub fn gui_testing( Transform2d(Mat3::from_scale_angle_translation( vec2(0.25, 0.05), 0., - vec2(0.5, 0.) + vec2(0.5, 0.25) )), ProgressbarComponent { progress: 0.5 From 7c8a0fb66b18a074d39e1cf81fdc93b6869bf4bc Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 00:08:32 +0100 Subject: [PATCH 060/160] progressbar shader fix --- kubi/shaders/gui/progressbar.vert | 4 ++-- kubi/src/gui.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kubi/shaders/gui/progressbar.vert b/kubi/shaders/gui/progressbar.vert index 35ca9c7..9d48236 100644 --- a/kubi/shaders/gui/progressbar.vert +++ b/kubi/shaders/gui/progressbar.vert @@ -1,12 +1,12 @@ #version 150 core in vec2 position; -out vec2 uv; +out vec2 v_uv; uniform mat4 ui_view; uniform mat3 transform; void main() { - uv = position; + v_uv = position; vec2 transformed = (transform * vec3(position, 1.)).xy; gl_Position = ui_view * vec4(transformed, 0., 1.); } diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index 41069ba..8662cab 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -53,7 +53,7 @@ pub fn gui_testing( vec2(0.5, 0.25) )), ProgressbarComponent { - progress: 0.5 + progress: 0.33 }, PrimaryColor::default(), SecondaryColor::default(), From 2fc8db67400e6399fdb3888683de4e42d230d144 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 00:46:20 +0100 Subject: [PATCH 061/160] gui changes, use glsl 3.0 es --- kubi/shaders/colored.frag | 4 ++- kubi/shaders/colored.vert | 4 ++- kubi/shaders/gui/progressbar.frag | 4 ++- kubi/shaders/gui/progressbar.vert | 2 +- kubi/shaders/selection_box.frag | 4 ++- kubi/shaders/selection_box.vert | 4 ++- kubi/shaders/world.frag | 5 +++- kubi/shaders/world.vert | 4 ++- kubi/src/events.rs | 16 +++++++++++- kubi/src/gui.rs | 41 ++++++++++++++++++++++--------- kubi/src/init.rs | 14 ++++++++--- kubi/src/main.rs | 9 ++++--- 12 files changed, 83 insertions(+), 28 deletions(-) diff --git a/kubi/shaders/colored.frag b/kubi/shaders/colored.frag index 3e09c7a..b7a0615 100644 --- a/kubi/shaders/colored.frag +++ b/kubi/shaders/colored.frag @@ -1,4 +1,6 @@ -#version 150 core +#version 300 es + +precision highp float; out vec4 out_color; uniform vec4 color; diff --git a/kubi/shaders/colored.vert b/kubi/shaders/colored.vert index 083513e..c6b3ef8 100644 --- a/kubi/shaders/colored.vert +++ b/kubi/shaders/colored.vert @@ -1,4 +1,6 @@ -#version 150 core +#version 300 es + +precision highp float; in vec3 position; uniform mat4 model; diff --git a/kubi/shaders/gui/progressbar.frag b/kubi/shaders/gui/progressbar.frag index 1474e79..e598692 100644 --- a/kubi/shaders/gui/progressbar.frag +++ b/kubi/shaders/gui/progressbar.frag @@ -1,4 +1,6 @@ -#version 150 core +#version 300 es + +precision highp float; in vec2 v_uv; out vec4 out_color; diff --git a/kubi/shaders/gui/progressbar.vert b/kubi/shaders/gui/progressbar.vert index 9d48236..2b43f0c 100644 --- a/kubi/shaders/gui/progressbar.vert +++ b/kubi/shaders/gui/progressbar.vert @@ -1,4 +1,4 @@ -#version 150 core +#version 300 es in vec2 position; out vec2 v_uv; diff --git a/kubi/shaders/selection_box.frag b/kubi/shaders/selection_box.frag index 42b54ed..d18a665 100644 --- a/kubi/shaders/selection_box.frag +++ b/kubi/shaders/selection_box.frag @@ -1,4 +1,6 @@ -#version 150 core +#version 300 es + +precision highp float; out vec4 color; uniform vec4 u_color; diff --git a/kubi/shaders/selection_box.vert b/kubi/shaders/selection_box.vert index f825013..049488d 100644 --- a/kubi/shaders/selection_box.vert +++ b/kubi/shaders/selection_box.vert @@ -1,4 +1,6 @@ -#version 150 core +#version 300 es + +precision highp float; in vec3 position; uniform ivec3 u_position; diff --git a/kubi/shaders/world.frag b/kubi/shaders/world.frag index 566efaf..f6054c2 100644 --- a/kubi/shaders/world.frag +++ b/kubi/shaders/world.frag @@ -1,4 +1,7 @@ -#version 150 core +#version 300 es + +precision highp float; +precision lowp sampler2DArray; in vec3 v_normal; in vec2 v_uv; diff --git a/kubi/shaders/world.vert b/kubi/shaders/world.vert index de3d2e7..996a1ec 100644 --- a/kubi/shaders/world.vert +++ b/kubi/shaders/world.vert @@ -1,4 +1,6 @@ -#version 150 core +#version 300 es + +precision highp float; //TODO pack this data: // uint position_normal_uv diff --git a/kubi/src/events.rs b/kubi/src/events.rs index b7154da..45fcfff 100644 --- a/kubi/src/events.rs +++ b/kubi/src/events.rs @@ -1,6 +1,7 @@ use glam::UVec2; -use shipyard::{World, Component, AllStoragesViewMut, SparseSet}; +use shipyard::{World, Component, AllStoragesViewMut, SparseSet, NonSendSync, UniqueView}; use glium::glutin::event::{Event, DeviceEvent, DeviceId, WindowEvent}; +use crate::rendering::Renderer; pub mod player_actions; @@ -50,6 +51,19 @@ pub fn process_glutin_events(world: &mut World, event: &Event<'_, ()>) { } } +pub fn initial_resize_event( + mut storages: AllStoragesViewMut, +) { + let (w, h) = { + let renderer = storages.borrow::>>().unwrap(); + renderer.display.get_framebuffer_dimensions() + }; + storages.add_entity(( + EventComponent, + WindowResizedEvent(UVec2::new(w, h)) + )); +} + pub fn clear_events( mut all_storages: AllStoragesViewMut, ) { diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index 8662cab..8f78889 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -1,6 +1,6 @@ -use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, AllStoragesViewMut}; -use glam::{Vec2, Vec4, Mat3, vec2, Mat4}; -use crate::{color::color_hex, transform::Transform2d}; +use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, AllStoragesViewMut, View, UniqueView, NonSendSync, UniqueViewMut, IntoIter}; +use glam::{Vec4, Mat3, vec2, Mat4}; +use crate::{color::color_hex, transform::Transform2d, events::WindowResizedEvent, rendering::Renderer}; pub mod text_widget; pub mod progressbar; @@ -8,7 +8,7 @@ pub mod progressbar; use progressbar::{render_progressbars, ProgressbarComponent}; //TODO compute gui scale on window resize -#[derive(Unique, Clone, Copy, Debug)] +#[derive(Unique, Clone, Copy, Debug, Default)] pub struct GuiView(pub Mat4); #[derive(Component, Clone, Copy, Debug, Default)] @@ -30,27 +30,44 @@ impl Default for SecondaryColor { } } +fn update_gui_view( + mut view: UniqueViewMut, + resize: View, +) { + let Some(&size) = resize.iter().next() else { + return + }; + let [w, h] = size.0.to_array(); + view.0 = Mat4::orthographic_rh_gl(0.0, w as f32, h as f32, 0.0, -1.0, 1.0); +} + +pub fn init_gui( + storages: AllStoragesView +) { + storages.add_unique(GuiView::default()); +} + +pub fn update_gui() -> Workload { + ( + update_gui_view + ).into_workload() +} + pub fn render_gui() -> Workload { ( render_progressbars ).into_workload() } -pub fn init_gui( - storages: AllStoragesView, -) { - storages.add_unique(GuiView(Mat4::orthographic_rh_gl(0.0, 1.0, 1.0, 0.0, 0.0, 1.0))); -} - pub fn gui_testing( mut storages: AllStoragesViewMut, ) { storages.add_entity(( GuiComponent, Transform2d(Mat3::from_scale_angle_translation( - vec2(0.25, 0.05), + vec2(1920., 16.), 0., - vec2(0.5, 0.25) + vec2(0., 0.) )), ProgressbarComponent { progress: 0.33 diff --git a/kubi/src/init.rs b/kubi/src/init.rs index 4f96843..ad6d2b2 100644 --- a/kubi/src/init.rs +++ b/kubi/src/init.rs @@ -1,11 +1,17 @@ -use std::net::SocketAddr; -use shipyard::AllStoragesView; -use std::env; +use shipyard::{AllStoragesView, NonSendSync, UniqueView}; +use glium::{Version, Api}; +use std::{env, net::SocketAddr}; use crate::{ networking::{GameType, ServerAddress}, - state::GameState + state::GameState, rendering::Renderer }; +pub fn assert_renderer( + renderer: NonSendSync> +) { + assert!(renderer.display.is_glsl_version_supported(&Version(Api::GlEs, 3, 0)), "GLES 3.0 is not supported"); +} + pub fn initialize_from_args( all_storages: AllStoragesView, ) { diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 0440b0b..3505389 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -48,7 +48,7 @@ use settings::load_settings; use camera::compute_cameras; use events::{ clear_events, process_glutin_events, - player_actions::generate_move_events + player_actions::generate_move_events, initial_resize_event }; use input::{init_input, process_inputs}; use fly_controller::update_controllers; @@ -67,11 +67,13 @@ use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; use state::{is_ingame, is_ingame_or_loading, is_loading}; -use init::initialize_from_args; -use gui::{render_gui, init_gui, gui_testing}; +use init::{initialize_from_args, assert_renderer}; +use gui::{render_gui, init_gui, gui_testing, update_gui}; fn startup() -> Workload { ( + assert_renderer, + initial_resize_event, load_settings, load_prefabs, init_primitives, @@ -106,6 +108,7 @@ fn update() -> Workload { apply_queued_blocks, ).into_workload().run_if(is_ingame), compute_cameras, + update_gui, ).into_workload() } fn render() -> Workload { From 54004ee5debc4ff7ba88112281e4c8fc9ff457a5 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 00:49:05 +0100 Subject: [PATCH 062/160] move assert_renderer to --- kubi/src/init.rs | 11 ++--------- kubi/src/main.rs | 3 ++- kubi/src/rendering.rs | 11 ++++++++++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/kubi/src/init.rs b/kubi/src/init.rs index ad6d2b2..6f35e85 100644 --- a/kubi/src/init.rs +++ b/kubi/src/init.rs @@ -1,17 +1,10 @@ -use shipyard::{AllStoragesView, NonSendSync, UniqueView}; -use glium::{Version, Api}; +use shipyard::AllStoragesView; use std::{env, net::SocketAddr}; use crate::{ networking::{GameType, ServerAddress}, - state::GameState, rendering::Renderer + state::GameState }; -pub fn assert_renderer( - renderer: NonSendSync> -) { - assert!(renderer.display.is_glsl_version_supported(&Version(Api::GlEs, 3, 0)), "GLES 3.0 is not supported"); -} - pub fn initialize_from_args( all_storages: AllStoragesView, ) { diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 3505389..d0aeb98 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -57,6 +57,7 @@ use rendering::{ RenderTarget, BackgroundColor, clear_background, + assert_renderer, primitives::init_primitives, selection_box::render_selection_box, world::draw_world, @@ -67,7 +68,7 @@ use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; use state::{is_ingame, is_ingame_or_loading, is_loading}; -use init::{initialize_from_args, assert_renderer}; +use init::initialize_from_args; use gui::{render_gui, init_gui, gui_testing, update_gui}; fn startup() -> Workload { diff --git a/kubi/src/rendering.rs b/kubi/src/rendering.rs index 9389e76..e6d740c 100644 --- a/kubi/src/rendering.rs +++ b/kubi/src/rendering.rs @@ -1,6 +1,7 @@ use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut}; use glium::{ - Display, Surface, + Display, Surface, + Version, Api, glutin::{ event_loop::EventLoop, window::WindowBuilder, @@ -34,10 +35,18 @@ impl Renderer { .with_gl_profile(GlProfile::Core); let display = Display::new(wb, cb, event_loop) .expect("Failed to create a glium Display"); + log::info!("renderer: {}", display.get_opengl_renderer_string()); + log::info!("oepngl {}", display.get_opengl_version_string()); Self { display } } } +pub fn assert_renderer( + renderer: NonSendSync> +) { + assert!(renderer.display.is_glsl_version_supported(&Version(Api::GlEs, 3, 0)), "GLES 3.0 is not supported"); +} + pub fn clear_background( mut target: NonSendSync>, color: UniqueView, From 06e94ccb463a198d3634d59b27afc3343c52d02c Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 00:56:03 +0100 Subject: [PATCH 063/160] assert renderer in init stage --- kubi/src/main.rs | 2 -- kubi/src/rendering.rs | 14 +++++--------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/kubi/src/main.rs b/kubi/src/main.rs index d0aeb98..0d4294f 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -57,7 +57,6 @@ use rendering::{ RenderTarget, BackgroundColor, clear_background, - assert_renderer, primitives::init_primitives, selection_box::render_selection_box, world::draw_world, @@ -73,7 +72,6 @@ use gui::{render_gui, init_gui, gui_testing, update_gui}; fn startup() -> Workload { ( - assert_renderer, initial_resize_event, load_settings, load_prefabs, diff --git a/kubi/src/rendering.rs b/kubi/src/rendering.rs index e6d740c..1e234da 100644 --- a/kubi/src/rendering.rs +++ b/kubi/src/rendering.rs @@ -1,4 +1,4 @@ -use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut}; +use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut, AllStoragesView}; use glium::{ Display, Surface, Version, Api, @@ -35,18 +35,14 @@ impl Renderer { .with_gl_profile(GlProfile::Core); let display = Display::new(wb, cb, event_loop) .expect("Failed to create a glium Display"); - log::info!("renderer: {}", display.get_opengl_renderer_string()); - log::info!("oepngl {}", display.get_opengl_version_string()); + log::info!("Renderer: {}", display.get_opengl_renderer_string()); + log::info!("OpenGL {}", display.get_opengl_version_string()); + log::info!("Supports GLES {:?}", display.get_supported_glsl_version()); + assert!(display.is_glsl_version_supported(&Version(Api::GlEs, 3, 0)), "GLES 3.0 is not supported"); Self { display } } } -pub fn assert_renderer( - renderer: NonSendSync> -) { - assert!(renderer.display.is_glsl_version_supported(&Version(Api::GlEs, 3, 0)), "GLES 3.0 is not supported"); -} - pub fn clear_background( mut target: NonSendSync>, color: UniqueView, From 6354d8bab4c3ce086b7ad77e4f34b92f11c57e8f Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 00:57:57 +0100 Subject: [PATCH 064/160] reorder --- kubi/src/main.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 0d4294f..0edfc40 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -128,14 +128,15 @@ fn after_frame_end() -> Workload { } fn main() { + //Init env_logger logging::init(); - //Create event loop - let event_loop = EventLoop::new(); - //Create a shipyard world let mut world = World::new(); + //Create event loop + let event_loop = EventLoop::new(); + //Add systems and uniques, Init and load things world.add_unique_non_send_sync(Renderer::init(&event_loop)); world.add_unique(BackgroundColor(vec3(0.5, 0.5, 1.))); From 4e357af95981f11302c983ae99e55b4eb29fea92 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 01:20:54 +0100 Subject: [PATCH 065/160] use windows subsystem attach console on release builds --- kubi/Cargo.toml | 3 +++ kubi/src/fly_controller.rs | 2 +- kubi/src/logging.rs | 6 ++---- kubi/src/main.rs | 16 ++++++++++++++-- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index ace8bc5..536897f 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -19,3 +19,6 @@ nohash-hasher = "0.2.0" anyhow = "1.0" flume = "0.10" gilrs = { version = "0.10", default_features = false, features = ["xinput"] } + +[target.'cfg(target_os = "windows")'.dependencies] +winapi = { version = "0.3" } diff --git a/kubi/src/fly_controller.rs b/kubi/src/fly_controller.rs index 2822d2a..81b5ea8 100644 --- a/kubi/src/fly_controller.rs +++ b/kubi/src/fly_controller.rs @@ -13,7 +13,7 @@ pub fn update_controllers() -> Workload { ).into_workload() } -const MAX_PITCH: f32 = PI/2. - 0.025; +const MAX_PITCH: f32 = PI/2. - 0.05; fn update_look( controllers: View, diff --git a/kubi/src/logging.rs b/kubi/src/logging.rs index c3b8be7..14d12ce 100644 --- a/kubi/src/logging.rs +++ b/kubi/src/logging.rs @@ -5,10 +5,8 @@ use log::Level; use std::io::Write; pub fn init() { - let mut env = Env::default(); - if cfg!(debug_assertions) { - env = env.filter_or("RUST_LOG", "trace,gilrs=warn,rusty_xinput=warn"); - } + let env = Env::default() + .filter_or("RUST_LOG", "trace,gilrs=warn,rusty_xinput=warn"); Builder::from_env(env) .format(|buf, record| { let mut level_style = buf.style(); diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 0edfc40..e19e65d 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -1,5 +1,8 @@ -// allowed because systems often need a lot of arguments -#![allow(clippy::too_many_arguments)] +#![cfg_attr( + all(windows, not(debug_assertions)), + windows_subsystem = "windows" +)] +#![allow(clippy::too_many_arguments)] // allowed because systems often need a lot of arguments use shipyard::{ World, Workload, IntoWorkload, @@ -127,7 +130,16 @@ fn after_frame_end() -> Workload { ).into_workload() } +#[cfg(all(windows, not(debug_assertions)))] +fn attach_console() { + use winapi::um::wincon::{AttachConsole, ATTACH_PARENT_PROCESS}; + unsafe { AttachConsole(ATTACH_PARENT_PROCESS); } +} + fn main() { + //Attach console on release builds on windows + #[cfg(all(windows, not(debug_assertions)))] attach_console(); + //Init env_logger logging::init(); From 2f23f39604e8e75e70d5f452afe9c11515b1ebb8 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 01:47:37 +0100 Subject: [PATCH 066/160] uwu --- kubi/src/gui.rs | 34 +++++++++++++++++----------------- kubi/src/init.rs | 12 ++++++------ kubi/src/loading_screen.rs | 31 +++++++++++++++++++++++++++++++ kubi/src/main.rs | 19 ++++++++++++------- kubi/src/rendering.rs | 2 +- kubi/src/state.rs | 25 +++++++++++++++++++++++-- kubi/src/world/loading.rs | 14 -------------- 7 files changed, 90 insertions(+), 47 deletions(-) create mode 100644 kubi/src/loading_screen.rs diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index 8f78889..73ac0d9 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -59,20 +59,20 @@ pub fn render_gui() -> Workload { ).into_workload() } -pub fn gui_testing( - mut storages: AllStoragesViewMut, -) { - storages.add_entity(( - GuiComponent, - Transform2d(Mat3::from_scale_angle_translation( - vec2(1920., 16.), - 0., - vec2(0., 0.) - )), - ProgressbarComponent { - progress: 0.33 - }, - PrimaryColor::default(), - SecondaryColor::default(), - )); -} +// pub fn gui_testing( +// mut storages: AllStoragesViewMut, +// ) { +// storages.add_entity(( +// GuiComponent, +// Transform2d(Mat3::from_scale_angle_translation( +// vec2(1920., 16.), +// 0., +// vec2(0., 0.) +// )), +// ProgressbarComponent { +// progress: 0.33 +// }, +// PrimaryColor::default(), +// SecondaryColor::default(), +// )); +// } diff --git a/kubi/src/init.rs b/kubi/src/init.rs index 6f35e85..24536c6 100644 --- a/kubi/src/init.rs +++ b/kubi/src/init.rs @@ -1,21 +1,21 @@ -use shipyard::AllStoragesView; -use std::{env, net::SocketAddr}; +use shipyard::{AllStoragesViewMut, UniqueViewMut}; +use std::{env, net::SocketAddr, borrow::BorrowMut}; use crate::{ networking::{GameType, ServerAddress}, - state::GameState + state::{GameState, NextState} }; pub fn initialize_from_args( - all_storages: AllStoragesView, + mut all_storages: AllStoragesViewMut, ) { let args: Vec = env::args().collect(); if args.len() > 1 { let address = args[1].parse::().expect("invalid address"); all_storages.add_unique(GameType::Muliplayer); - all_storages.add_unique(GameState::Connecting); all_storages.add_unique(ServerAddress(address)); + all_storages.borrow::>().unwrap().0 = Some(GameState::Connecting); } else { all_storages.add_unique(GameType::Singleplayer); - all_storages.add_unique(GameState::LoadingWorld); + all_storages.borrow::>().unwrap().0 = Some(GameState::LoadingWorld); } } diff --git a/kubi/src/loading_screen.rs b/kubi/src/loading_screen.rs new file mode 100644 index 0000000..6ddb4e0 --- /dev/null +++ b/kubi/src/loading_screen.rs @@ -0,0 +1,31 @@ +use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload}; +use crate::{ + world::ChunkStorage, + state::GameState +}; + +pub fn insert_progressbar() { + +} + + +pub fn switch_to_ingame_if_loaded( + world: UniqueView, + mut state: UniqueViewMut +) { + if world.chunks.is_empty() { + return + } + if world.chunks.iter().all(|(_, chunk)| { + chunk.desired_state.matches(chunk.current_state) + }) { + *state = GameState::InGame; + } +} + +pub fn update_loading_screen() -> Workload { + ( + insert_progressbar, + switch_to_ingame_if_loaded + ).into_workload() +} diff --git a/kubi/src/main.rs b/kubi/src/main.rs index e19e65d..d29b4c7 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -38,10 +38,11 @@ pub(crate) mod gui; pub(crate) mod networking; pub(crate) mod init; pub(crate) mod color; +pub(crate) mod loading_screen; use world::{ init_game_world, - loading::{update_loaded_world_around_player, switch_to_ingame_if_loaded}, + loading::update_loaded_world_around_player, raycast::update_raycasts, queue::apply_queued_blocks }; @@ -50,8 +51,10 @@ use prefabs::load_prefabs; use settings::load_settings; use camera::compute_cameras; use events::{ - clear_events, process_glutin_events, - player_actions::generate_move_events, initial_resize_event + clear_events, + process_glutin_events, + initial_resize_event, + player_actions::generate_move_events, }; use input::{init_input, process_inputs}; use fly_controller::update_controllers; @@ -69,9 +72,10 @@ use block_placement::block_placement_system; use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; -use state::{is_ingame, is_ingame_or_loading, is_loading}; +use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state}; use init::initialize_from_args; -use gui::{render_gui, init_gui, gui_testing, update_gui}; +use gui::{render_gui, init_gui, update_gui}; +use loading_screen::update_loading_screen; fn startup() -> Workload { ( @@ -80,11 +84,11 @@ fn startup() -> Workload { load_prefabs, init_primitives, insert_lock_state, + init_state, initialize_from_args, lock_cursor_now, init_input, init_gui, - gui_testing, init_game_world, spawn_player, insert_control_flow_unique, @@ -97,7 +101,7 @@ fn update() -> Workload { process_inputs, exit_on_esc, ( - switch_to_ingame_if_loaded, + update_loading_screen, ).into_workload().run_if(is_loading), ( update_loaded_world_around_player, @@ -111,6 +115,7 @@ fn update() -> Workload { ).into_workload().run_if(is_ingame), compute_cameras, update_gui, + update_state, ).into_workload() } fn render() -> Workload { diff --git a/kubi/src/rendering.rs b/kubi/src/rendering.rs index 1e234da..a288b3a 100644 --- a/kubi/src/rendering.rs +++ b/kubi/src/rendering.rs @@ -8,7 +8,7 @@ use glium::{ ContextBuilder, GlProfile }, }; -use glam::Vec3; +use glam::{Vec3, UVec2}; pub mod primitives; pub mod world; diff --git a/kubi/src/state.rs b/kubi/src/state.rs index 1f1297f..305f7c4 100644 --- a/kubi/src/state.rs +++ b/kubi/src/state.rs @@ -1,13 +1,34 @@ -use shipyard::{Unique, UniqueView}; +use shipyard::{Unique, UniqueView, UniqueViewMut, AllStoragesView}; +use std::mem::take; -#[derive(Unique, PartialEq, Eq)] +#[derive(Unique, PartialEq, Eq, Default, Clone, Copy)] #[track(All)] pub enum GameState { + #[default] + Initial, Connecting, LoadingWorld, InGame } +#[derive(Unique, PartialEq, Eq, Default, Clone, Copy)] +#[track(All)] +pub struct NextState(pub Option); + +pub fn init_state( + all_storages: AllStoragesView, +) { + all_storages.add_unique(GameState::default()); + all_storages.add_unique(NextState::default()); +} + +pub fn update_state( + mut state: UniqueViewMut, + mut next: UniqueViewMut, +) { + *state = take(&mut next.0).unwrap_or(*state); +} + pub fn is_ingame( state: UniqueView ) -> bool { diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index 307b898..e5c01ce 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -238,17 +238,3 @@ fn process_completed_tasks( } } } - -pub fn switch_to_ingame_if_loaded( - world: UniqueView, - mut state: UniqueViewMut -) { - if world.chunks.is_empty() { - return - } - if world.chunks.iter().all(|(_, chunk)| { - chunk.desired_state.matches(chunk.current_state) - }) { - *state = GameState::InGame; - } -} From dbb92232bcede3436959dcc066dc777680345bbc Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 02:36:11 +0100 Subject: [PATCH 067/160] loading screen --- kubi/src/gui/progressbar.rs | 13 +++---- kubi/src/loading_screen.rs | 77 +++++++++++++++++++++++++++++++++---- kubi/src/main.rs | 4 +- kubi/src/rendering.rs | 30 ++++++++++++++- 4 files changed, 107 insertions(+), 17 deletions(-) diff --git a/kubi/src/gui/progressbar.rs b/kubi/src/gui/progressbar.rs index 3e848c9..9a945c7 100644 --- a/kubi/src/gui/progressbar.rs +++ b/kubi/src/gui/progressbar.rs @@ -1,4 +1,4 @@ -use shipyard::{UniqueView, UniqueViewMut, NonSendSync, View, Component, IntoIter}; +use shipyard::{UniqueView, UniqueViewMut, NonSendSync, View, Component, IntoIter, IntoWithId, Get}; use glium::{Surface, uniform, DrawParameters}; use crate::{ prefabs::ProgressbarShaderPrefab, @@ -25,10 +25,9 @@ pub fn render_progressbars( primary: View, secondary: View, ) { - for (_, transform, progress, pri, sec) in (&components, &transforms, &progressbars, &primary, &secondary).iter() { - //TODO do this properly - let pri = Some(pri).copied(); - let sec = Some(sec).copied(); + for (eid, (_, transform, progress)) in (&components, &transforms, &progressbars).iter().with_id() { + let primary_color = primary.get(eid).copied().unwrap_or_default(); + let secondary_color = secondary.get(eid).copied().unwrap_or_default(); target.0.draw( &rect.0, &rect.1, @@ -37,8 +36,8 @@ pub fn render_progressbars( transform: transform.0.to_cols_array_2d(), ui_view: view.0.to_cols_array_2d(), progress: progress.progress, - color: pri.unwrap_or_default().0.to_array(), - bg_color: sec.unwrap_or_default().0.to_array(), + color: primary_color.0.to_array(), + bg_color: secondary_color.0.to_array(), }, &DrawParameters::default() ).unwrap(); diff --git a/kubi/src/loading_screen.rs b/kubi/src/loading_screen.rs index 6ddb4e0..f003174 100644 --- a/kubi/src/loading_screen.rs +++ b/kubi/src/loading_screen.rs @@ -1,17 +1,62 @@ -use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload}; +use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload, WorkloadModificator, EntityId, Unique, AllStoragesViewMut, ViewMut, View, IntoIter, Get}; +use glam::{Mat3, vec2}; use crate::{ world::ChunkStorage, - state::GameState + state::{GameState, NextState}, + transform::Transform2d, + gui::{ + GuiComponent, + progressbar::ProgressbarComponent + }, rendering::{WindowSize, if_resized}, }; -pub fn insert_progressbar() { +#[derive(Unique, Clone, Copy)] +struct ProgressbarId(EntityId); +fn spawn_loading_screen( + mut storages: AllStoragesViewMut, +) { + let size = *storages.borrow::>().unwrap(); + let entity = storages.add_entity(( + GuiComponent, + Transform2d(Mat3::from_scale_angle_translation( + vec2(size.0.x as f32, 16.), + 0., + vec2(0., 0.) + )), + ProgressbarComponent { + progress: 0.33 + }, + )); + storages.add_unique(ProgressbarId(entity)); } +fn resize_progress_bar( + size: UniqueView, + bar: UniqueView, + mut transforms: ViewMut +) { + let mut trans = (&mut transforms).get(bar.0).unwrap(); + trans.0.x_axis.x = size.0.x as f32; +} -pub fn switch_to_ingame_if_loaded( +fn update_progress_bar_progress ( world: UniqueView, - mut state: UniqueViewMut + mut bar: ViewMut, + eid: UniqueView, +) { + let bar = (&mut bar).get(eid.0).unwrap(); + let loaded = world.chunks.iter().fold(0, |acc, (&_, chunk)| { + acc + chunk.desired_state.matches(chunk.current_state) as usize + }); + let total = world.chunks.len(); + let progress = loaded as f32 / total as f32; + bar.progress = progress; +} + +fn switch_to_ingame_if_loaded( + world: UniqueView, + mut state: UniqueViewMut ) { if world.chunks.is_empty() { return @@ -19,13 +64,29 @@ pub fn switch_to_ingame_if_loaded( if world.chunks.iter().all(|(_, chunk)| { chunk.desired_state.matches(chunk.current_state) }) { - *state = GameState::InGame; + state.0 = Some(GameState::InGame); + } +} + +fn despawn_loading_screen_if_switching_state( + mut storages: AllStoragesViewMut, +) { + let next = *storages.borrow::>().unwrap(); + if let Some(state) = next.0 { + if state != GameState::LoadingWorld { + let progress_bar = storages.borrow::>().unwrap().0; + storages.delete_entity(progress_bar); + storages.remove_unique::().unwrap(); + } } } pub fn update_loading_screen() -> Workload { ( - insert_progressbar, - switch_to_ingame_if_loaded + spawn_loading_screen.into_workload().run_if_missing_unique::(), + resize_progress_bar.into_workload().run_if(if_resized), + update_progress_bar_progress, + switch_to_ingame_if_loaded, + despawn_loading_screen_if_switching_state, ).into_workload() } diff --git a/kubi/src/main.rs b/kubi/src/main.rs index d29b4c7..c743c24 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -66,7 +66,7 @@ use rendering::{ primitives::init_primitives, selection_box::render_selection_box, world::draw_world, - world::draw_current_chunk_border, + world::draw_current_chunk_border, init_window_size, update_window_size, }; use block_placement::block_placement_system; use delta_time::{DeltaTime, init_delta_time}; @@ -80,6 +80,7 @@ use loading_screen::update_loading_screen; fn startup() -> Workload { ( initial_resize_event, + init_window_size, load_settings, load_prefabs, init_primitives, @@ -97,6 +98,7 @@ fn startup() -> Workload { } fn update() -> Workload { ( + update_window_size, update_cursor_lock_state, process_inputs, exit_on_esc, diff --git a/kubi/src/rendering.rs b/kubi/src/rendering.rs index a288b3a..f0b621a 100644 --- a/kubi/src/rendering.rs +++ b/kubi/src/rendering.rs @@ -1,4 +1,4 @@ -use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut, AllStoragesView}; +use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut, View, IntoIter, AllStoragesView}; use glium::{ Display, Surface, Version, Api, @@ -9,6 +9,7 @@ use glium::{ }, }; use glam::{Vec3, UVec2}; +use crate::events::WindowResizedEvent; pub mod primitives; pub mod world; @@ -20,6 +21,9 @@ pub struct RenderTarget(pub glium::Frame); #[derive(Unique)] pub struct BackgroundColor(pub Vec3); +#[derive(Unique, Clone, Copy)] +pub struct WindowSize(pub UVec2); + #[derive(Unique)] pub struct Renderer { pub display: Display @@ -49,3 +53,27 @@ pub fn clear_background( ) { target.0.clear_color_srgb_and_depth((color.0.x, color.0.y, color.0.z, 1.), 1.); } + +//not sure if this belongs here + +pub fn init_window_size( + storages: AllStoragesView, +) { + let size = storages.borrow::>().unwrap().iter().next().unwrap().0; + storages.add_unique(WindowSize(size)) +} + +pub fn update_window_size( + mut win_size: UniqueViewMut, + resize: View, +) { + if let Some(resize) = resize.iter().next() { + win_size.0 = resize.0; + } +} + +pub fn if_resized ( + resize: View, +) -> bool { + resize.len() > 0 +} From c06869c5cbe16f3db00081ccb07c48669cd9c84e Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 02:44:17 +0100 Subject: [PATCH 068/160] slow down chunk ops while loading --- kubi/src/world/loading.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index e5c01ce..3b6fb83 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -14,8 +14,8 @@ use super::{ tasks::{ChunkTaskManager, ChunkTaskResponse, ChunkTask}, }; -//todo limit task starts insted -const MAX_CHUNK_OPS: usize = 8; +const MAX_CHUNK_OPS_INGAME: usize = 6; +const MAX_CHUNK_OPS: usize = 32; pub fn update_loaded_world_around_player() -> Workload { ( @@ -233,8 +233,9 @@ fn process_completed_tasks( ops += 1; } } - if (ops >= MAX_CHUNK_OPS) && matches!(*state, GameState::InGame) { - break - } + if ops >= match *state { + GameState::InGame => MAX_CHUNK_OPS_INGAME, + _ => MAX_CHUNK_OPS, + } { break } } } From 35886d9bed898c67f788b7e3c5ac5d16cf1eb985 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 02:46:34 +0100 Subject: [PATCH 069/160] log after load finish --- kubi/src/loading_screen.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kubi/src/loading_screen.rs b/kubi/src/loading_screen.rs index f003174..5ee6d08 100644 --- a/kubi/src/loading_screen.rs +++ b/kubi/src/loading_screen.rs @@ -64,6 +64,7 @@ fn switch_to_ingame_if_loaded( if world.chunks.iter().all(|(_, chunk)| { chunk.desired_state.matches(chunk.current_state) }) { + log::info!("Finished loadinf chunks"); state.0 = Some(GameState::InGame); } } From 8e9eeb1f3087a6781cef792b02562536468979e0 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 03:00:08 +0100 Subject: [PATCH 070/160] typo --- kubi/src/loading_screen.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi/src/loading_screen.rs b/kubi/src/loading_screen.rs index 5ee6d08..eb323a1 100644 --- a/kubi/src/loading_screen.rs +++ b/kubi/src/loading_screen.rs @@ -64,7 +64,7 @@ fn switch_to_ingame_if_loaded( if world.chunks.iter().all(|(_, chunk)| { chunk.desired_state.matches(chunk.current_state) }) { - log::info!("Finished loadinf chunks"); + log::info!("Finished loading chunks"); state.0 = Some(GameState::InGame); } } From aada43e8dc557aa8e35d5b4b2db37569f38b5d26 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 03:03:00 +0100 Subject: [PATCH 071/160] is_changing_state --- kubi/src/loading_screen.rs | 16 +++++++--------- kubi/src/state.rs | 6 ++++++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/kubi/src/loading_screen.rs b/kubi/src/loading_screen.rs index eb323a1..585a009 100644 --- a/kubi/src/loading_screen.rs +++ b/kubi/src/loading_screen.rs @@ -2,7 +2,7 @@ use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload, WorkloadModifi use glam::{Mat3, vec2}; use crate::{ world::ChunkStorage, - state::{GameState, NextState}, + state::{GameState, NextState, is_changing_state}, transform::Transform2d, gui::{ GuiComponent, @@ -72,13 +72,11 @@ fn switch_to_ingame_if_loaded( fn despawn_loading_screen_if_switching_state( mut storages: AllStoragesViewMut, ) { - let next = *storages.borrow::>().unwrap(); - if let Some(state) = next.0 { - if state != GameState::LoadingWorld { - let progress_bar = storages.borrow::>().unwrap().0; - storages.delete_entity(progress_bar); - storages.remove_unique::().unwrap(); - } + let state = storages.borrow::>().unwrap().0.unwrap(); + if state != GameState::LoadingWorld { + let progress_bar = storages.borrow::>().unwrap().0; + storages.delete_entity(progress_bar); + storages.remove_unique::().unwrap(); } } @@ -88,6 +86,6 @@ pub fn update_loading_screen() -> Workload { resize_progress_bar.into_workload().run_if(if_resized), update_progress_bar_progress, switch_to_ingame_if_loaded, - despawn_loading_screen_if_switching_state, + despawn_loading_screen_if_switching_state.into_workload().run_if(is_changing_state), ).into_workload() } diff --git a/kubi/src/state.rs b/kubi/src/state.rs index 305f7c4..3301964 100644 --- a/kubi/src/state.rs +++ b/kubi/src/state.rs @@ -29,6 +29,12 @@ pub fn update_state( *state = take(&mut next.0).unwrap_or(*state); } +pub fn is_changing_state( + state: UniqueView +) -> bool { + state.0.is_some() +} + pub fn is_ingame( state: UniqueView ) -> bool { From 28a82cf69efd2fe6cc6af1716eb906f7d0e956e1 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 20:26:03 +0100 Subject: [PATCH 072/160] server --- kubi-server/src/main.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index d091d78..9460db3 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -1,3 +1,14 @@ +use kubi_udp::server::{Server, ServerConfig}; +use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; + fn main() { - + let mut server: Server = Server::bind( + "0.0.0.0:1234".parse().unwrap(), + ServerConfig::default() + ).unwrap(); + loop { + if let Err(or) = server.update() { + println!("Server error: {or:?}") + } + } } From 055e6c3600f59de52ef058be876203a0f51ba306 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 20:36:58 +0100 Subject: [PATCH 073/160] ecs server --- kubi-server/Cargo.toml | 1 + kubi-server/src/main.rs | 45 +++++++++++++++++++++++++++++++++++------ kubi-udp/src/server.rs | 2 +- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 5dc3fc5..87c64dd 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" [dependencies] kubi-shared = { path = "../kubi-shared" } kubi-udp = { path = "../kubi-udp" } +shipyard = "0.6" diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index 9460db3..b82c528 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -1,14 +1,47 @@ +use shipyard::{World, AllStoragesView, Unique, Workload, IntoWorkload, UniqueView, UniqueViewMut}; use kubi_udp::server::{Server, ServerConfig}; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; -fn main() { - let mut server: Server = Server::bind( +#[derive(Unique)] +#[repr(transparent)] +pub struct UdpServer(Server); + +fn bind_server( + storages: AllStoragesView, +) { + let server: Server = Server::bind( "0.0.0.0:1234".parse().unwrap(), ServerConfig::default() ).unwrap(); - loop { - if let Err(or) = server.update() { - println!("Server error: {or:?}") - } + storages.add_unique(UdpServer(server)); +} + +fn update_server( + mut server: UniqueViewMut +) { + if let Err(error) = server.0.update() { + println!("Server error: {error:?}") + } +} + +fn initialize() -> Workload { + ( + bind_server, + ).into_workload() +} + +fn update() -> Workload { + ( + update_server, + ).into_workload() +} + +fn main() { + let world = World::new(); + world.add_workload(initialize); + world.add_workload(update); + world.run_workload(initialize).unwrap(); + loop { + world.run_workload(update).unwrap(); } } diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 1a0b537..905aefc 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -48,7 +48,7 @@ pub struct Server where S: Encode + Decode, R: Encode + Decode { clients: HashMap>, config: ServerConfig, event_queue: VecDeque>, - _s: PhantomData<*const S>, + _s: PhantomData, } impl Server where S: Encode + Decode, R: Encode + Decode { fn send_to_addr(&self, addr: SocketAddr, packet: IdServerPacket) -> Result<()> { From 3f47be435dcc9e4063e54b832473eec3b48da34a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 20:44:34 +0100 Subject: [PATCH 074/160] separate logging into a library --- Cargo.toml | 2 +- kubi-logging/Cargo.toml | 8 ++++++++ kubi/src/logging.rs => kubi-logging/src/lib.rs | 6 +++++- kubi-server/Cargo.toml | 2 ++ kubi-server/src/main.rs | 1 + kubi/Cargo.toml | 4 ++-- kubi/src/main.rs | 3 +-- 7 files changed, 20 insertions(+), 6 deletions(-) create mode 100644 kubi-logging/Cargo.toml rename kubi/src/logging.rs => kubi-logging/src/lib.rs (93%) diff --git a/Cargo.toml b/Cargo.toml index de197ad..ae1d7de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["kubi", "kubi-server", "kubi-shared", "kubi-udp"] +members = ["kubi", "kubi-server", "kubi-shared", "kubi-udp", "kubi-logging"] resolver = "2" [profile.release-with-debug] diff --git a/kubi-logging/Cargo.toml b/kubi-logging/Cargo.toml new file mode 100644 index 0000000..c88c172 --- /dev/null +++ b/kubi-logging/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "kubi-logging" +version = "0.1.0" +edition = "2021" + +[dependencies] +log = "0.4" +env_logger = "0.10" diff --git a/kubi/src/logging.rs b/kubi-logging/src/lib.rs similarity index 93% rename from kubi/src/logging.rs rename to kubi-logging/src/lib.rs index 14d12ce..84505f0 100644 --- a/kubi/src/logging.rs +++ b/kubi-logging/src/lib.rs @@ -1,9 +1,13 @@ -//! Custom env_logger options and styling +/// Custom env_logger options and styling use env_logger::{fmt::Color, Builder, Env}; use log::Level; use std::io::Write; +pub use log; +pub use env_logger; + +#[inline] pub fn init() { let env = Env::default() .filter_or("RUST_LOG", "trace,gilrs=warn,rusty_xinput=warn"); diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 87c64dd..e9ff2ba 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -6,4 +6,6 @@ edition = "2021" [dependencies] kubi-shared = { path = "../kubi-shared" } kubi-udp = { path = "../kubi-udp" } +kubi-logging = { path = "../kubi-logging" } +log = "*" shipyard = "0.6" diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index b82c528..82bd08a 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -37,6 +37,7 @@ fn update() -> Workload { } fn main() { + kubi_logging::init(); let world = World::new(); world.add_workload(initialize); world.add_workload(update); diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 536897f..50bf39a 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -6,11 +6,11 @@ edition = "2021" [dependencies] kubi-shared = { path = "../kubi-shared" } kubi-udp = { path = "../kubi-udp", optional = true } +kubi-logging = { path = "../kubi-logging" } +log = "*" glium = "0.32" glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } image = { version = "0.24", default_features = false, features = ["png"] } -log = "0.4" -env_logger = "0.10" strum = { version = "0.24", features = ["derive"] } hashbrown = "0.13" rayon = "1.6" diff --git a/kubi/src/main.rs b/kubi/src/main.rs index c743c24..d683794 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -18,7 +18,6 @@ use glium::{ use glam::vec3; use std::time::Instant; -mod logging; pub(crate) mod rendering; pub(crate) mod world; pub(crate) mod player; @@ -148,7 +147,7 @@ fn main() { #[cfg(all(windows, not(debug_assertions)))] attach_console(); //Init env_logger - logging::init(); + kubi_logging::init(); //Create a shipyard world let mut world = World::new(); From 6b65497263074f106a73434052e4cf7792809171 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 22:05:10 +0100 Subject: [PATCH 075/160] server --- kubi-server/src/main.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index 82bd08a..0525209 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -1,6 +1,7 @@ use shipyard::{World, AllStoragesView, Unique, Workload, IntoWorkload, UniqueView, UniqueViewMut}; use kubi_udp::server::{Server, ServerConfig}; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; +use std::{thread, time::Duration}; #[derive(Unique)] #[repr(transparent)] @@ -9,6 +10,7 @@ pub struct UdpServer(Server); fn bind_server( storages: AllStoragesView, ) { + log::info!("Binding server"); let server: Server = Server::bind( "0.0.0.0:1234".parse().unwrap(), ServerConfig::default() @@ -20,7 +22,7 @@ fn update_server( mut server: UniqueViewMut ) { if let Err(error) = server.0.update() { - println!("Server error: {error:?}") + log::error!("Server error: {error:?}") } } @@ -44,5 +46,6 @@ fn main() { world.run_workload(initialize).unwrap(); loop { world.run_workload(update).unwrap(); + thread::sleep(Duration::from_millis(16)); } } From 5307ba0c9ff471e3d6092cadd3004a7d0c27b6e1 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Fri, 10 Feb 2023 22:11:18 +0100 Subject: [PATCH 076/160] wip --- Server.toml | 4 ++++ kubi-server/Cargo.toml | 2 ++ kubi-server/src/main.rs | 10 ++++++++-- 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 Server.toml diff --git a/Server.toml b/Server.toml new file mode 100644 index 0000000..08a172e --- /dev/null +++ b/Server.toml @@ -0,0 +1,4 @@ +[server] +address = "0.0.0.0" +port = 1234 +max_clients = 254 diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index e9ff2ba..3e4255d 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -9,3 +9,5 @@ kubi-udp = { path = "../kubi-udp" } kubi-logging = { path = "../kubi-logging" } log = "*" shipyard = "0.6" +serde = "1.0" +toml = "0.7" diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index 0525209..ea6bfc4 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -1,7 +1,11 @@ use shipyard::{World, AllStoragesView, Unique, Workload, IntoWorkload, UniqueView, UniqueViewMut}; use kubi_udp::server::{Server, ServerConfig}; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; -use std::{thread, time::Duration}; +use std::{thread, time::Duration, net::SocketAddr}; + +#[derive(Unique)] +#[repr(transparent)] +pub struct ServerAddr(SocketAddr); #[derive(Unique)] #[repr(transparent)] @@ -10,7 +14,8 @@ pub struct UdpServer(Server); fn bind_server( storages: AllStoragesView, ) { - log::info!("Binding server"); + log::info!("Creating server..."); + let addr = storages.borrow::>().expect("No server addr found"); let server: Server = Server::bind( "0.0.0.0:1234".parse().unwrap(), ServerConfig::default() @@ -44,6 +49,7 @@ fn main() { world.add_workload(initialize); world.add_workload(update); world.run_workload(initialize).unwrap(); + log::info!("The server is now running"); loop { world.run_workload(update).unwrap(); thread::sleep(Duration::from_millis(16)); From f76fa8c70e6586a6d43adb0ed26e29e6dcd50457 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 00:37:24 +0100 Subject: [PATCH 077/160] server --- Server.toml | 3 +-- kubi-server/Cargo.toml | 5 +++++ kubi-server/src/client.rs | 4 ++++ kubi-server/src/config.rs | 23 +++++++++++++++++++++ kubi-server/src/main.rs | 39 +++++++++--------------------------- kubi-server/src/server.rs | 28 ++++++++++++++++++++++++++ kubi-server/src/transform.rs | 6 ++++++ kubi/Cargo.toml | 4 ++++ kubi/src/rendering/world.rs | 1 + 9 files changed, 81 insertions(+), 32 deletions(-) create mode 100644 kubi-server/src/client.rs create mode 100644 kubi-server/src/config.rs create mode 100644 kubi-server/src/server.rs create mode 100644 kubi-server/src/transform.rs diff --git a/Server.toml b/Server.toml index 08a172e..36d87ae 100644 --- a/Server.toml +++ b/Server.toml @@ -1,4 +1,3 @@ [server] -address = "0.0.0.0" -port = 1234 +address = "0.0.0.0:1234" max_clients = 254 diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 3e4255d..1b5c09a 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -11,3 +11,8 @@ log = "*" shipyard = "0.6" serde = "1.0" toml = "0.7" +glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } + +[features] +default = [] +unstable = ["glam/core-simd"] diff --git a/kubi-server/src/client.rs b/kubi-server/src/client.rs new file mode 100644 index 0000000..a0c57ac --- /dev/null +++ b/kubi-server/src/client.rs @@ -0,0 +1,4 @@ +use shipyard::Component; + +#[derive(Component)] +pub struct Client; diff --git a/kubi-server/src/config.rs b/kubi-server/src/config.rs new file mode 100644 index 0000000..a16dbf2 --- /dev/null +++ b/kubi-server/src/config.rs @@ -0,0 +1,23 @@ +use shipyard::{AllStoragesView, Unique}; +use serde::{Serialize, Deserialize}; +use std::{fs, net::SocketAddr}; + +#[derive(Serialize, Deserialize)] +pub struct ConfigTableServer { + pub address: SocketAddr, + pub max_clients: usize, +} + +#[derive(Unique, Serialize, Deserialize)] +pub struct ConfigTable { + pub server: ConfigTableServer +} + +pub fn read_config( + storages: AllStoragesView, +) { + log::info!("Reading config..."); + let config_str = fs::read_to_string("Server.toml").expect("No config file found"); + let config: ConfigTable = toml::from_str(&config_str).expect("Invalid configuration file"); + storages.add_unique(config); +} diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index ea6bfc4..6c0158e 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -1,38 +1,17 @@ -use shipyard::{World, AllStoragesView, Unique, Workload, IntoWorkload, UniqueView, UniqueViewMut}; -use kubi_udp::server::{Server, ServerConfig}; -use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; -use std::{thread, time::Duration, net::SocketAddr}; +use shipyard::{World, Workload, IntoWorkload}; +use std::{thread, time::Duration}; -#[derive(Unique)] -#[repr(transparent)] -pub struct ServerAddr(SocketAddr); +pub(crate) mod config; +pub(crate) mod server; +pub(crate) mod client; +pub(crate) mod transform; -#[derive(Unique)] -#[repr(transparent)] -pub struct UdpServer(Server); - -fn bind_server( - storages: AllStoragesView, -) { - log::info!("Creating server..."); - let addr = storages.borrow::>().expect("No server addr found"); - let server: Server = Server::bind( - "0.0.0.0:1234".parse().unwrap(), - ServerConfig::default() - ).unwrap(); - storages.add_unique(UdpServer(server)); -} - -fn update_server( - mut server: UniqueViewMut -) { - if let Err(error) = server.0.update() { - log::error!("Server error: {error:?}") - } -} +use config::read_config; +use server::{bind_server, update_server}; fn initialize() -> Workload { ( + read_config, bind_server, ).into_workload() } diff --git a/kubi-server/src/server.rs b/kubi-server/src/server.rs new file mode 100644 index 0000000..589b160 --- /dev/null +++ b/kubi-server/src/server.rs @@ -0,0 +1,28 @@ +use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut}; +use kubi_udp::server::{Server, ServerConfig}; +use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; +use crate::config::ConfigTable; + +#[derive(Unique)] +#[repr(transparent)] +pub struct UdpServer(Server); + +pub fn bind_server( + storages: AllStoragesView, +) { + log::info!("Creating server..."); + let config = storages.borrow::>().unwrap(); + let server: Server = Server::bind( + config.server.address, + ServerConfig { max_clients: config.server.max_clients } + ).unwrap(); + storages.add_unique(UdpServer(server)); +} + +pub fn update_server( + mut server: UniqueViewMut +) { + if let Err(error) = server.0.update() { + log::error!("Server error: {error:?}") + } +} diff --git a/kubi-server/src/transform.rs b/kubi-server/src/transform.rs new file mode 100644 index 0000000..5087b6c --- /dev/null +++ b/kubi-server/src/transform.rs @@ -0,0 +1,6 @@ +use shipyard::Component; +use glam::Mat4; + +#[derive(Component, Clone, Copy, Debug, Default)] +#[track(All)] +pub struct Transform(pub Mat4); diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 50bf39a..c88d405 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -22,3 +22,7 @@ gilrs = { version = "0.10", default_features = false, features = ["xinput"] } [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "0.3" } + +[features] +default = [] +unstable = ["glam/core-simd"] diff --git a/kubi/src/rendering/world.rs b/kubi/src/rendering/world.rs index a42136b..9029381 100644 --- a/kubi/src/rendering/world.rs +++ b/kubi/src/rendering/world.rs @@ -35,6 +35,7 @@ use crate::{ use super::{RenderTarget, primitives::cube::CubePrimitive}; #[derive(Clone, Copy)] +#[repr(C)] pub struct ChunkVertex { pub position: [f32; 3], pub normal: [f32; 3], From af62a3749b56116a9acfb87d140c6456c20194e2 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 01:32:59 +0100 Subject: [PATCH 078/160] some changes to server and shared crates --- kubi-server/Cargo.toml | 2 ++ kubi-server/src/client.rs | 31 ++++++++++++++++++++++++-- kubi-server/src/main.rs | 1 - kubi-server/src/transform.rs | 6 ----- kubi-shared/Cargo.toml | 1 + kubi-shared/src/lib.rs | 1 + {kubi => kubi-shared}/src/transform.rs | 0 kubi-udp/src/common.rs | 1 + kubi-udp/src/lib.rs | 1 + kubi-udp/src/server.rs | 4 ++-- kubi/src/main.rs | 3 ++- 11 files changed, 39 insertions(+), 12 deletions(-) delete mode 100644 kubi-server/src/transform.rs rename {kubi => kubi-shared}/src/transform.rs (100%) diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 1b5c09a..d2856d9 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -12,6 +12,8 @@ shipyard = "0.6" serde = "1.0" toml = "0.7" glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } +hashbrown = "0.13" +nohash-hasher = "0.2.0" [features] default = [] diff --git a/kubi-server/src/client.rs b/kubi-server/src/client.rs index a0c57ac..2508fa1 100644 --- a/kubi-server/src/client.rs +++ b/kubi-server/src/client.rs @@ -1,4 +1,31 @@ -use shipyard::Component; +use shipyard::{Component, EntityId}; +use hashbrown::HashMap; +use nohash_hasher::BuildNoHashHasher; +use kubi_udp::{ClientId, ClientIdRepr}; #[derive(Component)] -pub struct Client; +pub struct Client(ClientId); + + +// disconnected => connect => join => load => ingame +#[derive(Component)] +pub enum ClientJoinState { + /// Client has connected to the game, but haven't authenticated yet + Connected, + /// Client has joined the game, but haven't loaded the world yet + Joined, + /// Client is currently ingame + InGame, +} + +pub struct ClientMap(HashMap>); +impl ClientMap { + pub fn new() -> Self { + Self(HashMap::with_hasher(BuildNoHashHasher::default())) + } +} +impl Default for ClientMap { + fn default() -> Self { + Self::new() + } +} diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index 6c0158e..bb6f60e 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -4,7 +4,6 @@ use std::{thread, time::Duration}; pub(crate) mod config; pub(crate) mod server; pub(crate) mod client; -pub(crate) mod transform; use config::read_config; use server::{bind_server, update_server}; diff --git a/kubi-server/src/transform.rs b/kubi-server/src/transform.rs deleted file mode 100644 index 5087b6c..0000000 --- a/kubi-server/src/transform.rs +++ /dev/null @@ -1,6 +0,0 @@ -use shipyard::Component; -use glam::Mat4; - -#[derive(Component, Clone, Copy, Debug, Default)] -#[track(All)] -pub struct Transform(pub Mat4); diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index c42eb3b..7fb813f 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] glam = { version = "0.22", features = ["debug-glam-assert", "fast-math", "serde"] } +shipyard = "0.6" strum = { version = "0.24", features = ["derive"] } bincode = "2.0.0-rc" anyhow = "1.0" diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs index dd0e7a5..13cb165 100644 --- a/kubi-shared/src/lib.rs +++ b/kubi-shared/src/lib.rs @@ -2,3 +2,4 @@ pub mod blocks; pub mod networking; pub mod worldgen; pub mod chunk; +pub mod transform; diff --git a/kubi/src/transform.rs b/kubi-shared/src/transform.rs similarity index 100% rename from kubi/src/transform.rs rename to kubi-shared/src/transform.rs diff --git a/kubi-udp/src/common.rs b/kubi-udp/src/common.rs index 20e5a1e..76e92b2 100644 --- a/kubi-udp/src/common.rs +++ b/kubi-udp/src/common.rs @@ -1,4 +1,5 @@ use std::num::NonZeroU8; pub type ClientId = NonZeroU8; +pub type ClientIdRepr = u8; pub const MAX_CLIENTS: usize = u8::MAX as _; diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs index ec14b35..ae5678c 100644 --- a/kubi-udp/src/lib.rs +++ b/kubi-udp/src/lib.rs @@ -3,6 +3,7 @@ pub mod server; pub(crate) mod packet; pub(crate) mod common; pub use common::ClientId; +pub use common::ClientIdRepr; //pub(crate) trait Serializable: bincode::Encode + bincode::Decode {} pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 905aefc..f9a8322 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -10,7 +10,7 @@ use hashbrown::HashMap; use nohash_hasher::BuildNoHashHasher; use crate::{ BINCODE_CONFIG, - common::{ClientId, MAX_CLIENTS}, + common::{ClientId, ClientIdRepr, MAX_CLIENTS}, packet::{IdClientPacket, ClientPacket, ServerPacket, IdServerPacket} }; @@ -45,7 +45,7 @@ pub enum ServerEvent where T: Encode + Decode { pub struct Server where S: Encode + Decode, R: Encode + Decode { socket: UdpSocket, - clients: HashMap>, + clients: HashMap>, config: ServerConfig, event_queue: VecDeque>, _s: PhantomData, diff --git a/kubi/src/main.rs b/kubi/src/main.rs index d683794..924d481 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -18,11 +18,12 @@ use glium::{ use glam::vec3; use std::time::Instant; +pub use kubi_shared::transform; + pub(crate) mod rendering; pub(crate) mod world; pub(crate) mod player; pub(crate) mod prefabs; -pub(crate) mod transform; pub(crate) mod settings; pub(crate) mod camera; pub(crate) mod events; From 22054c61434d36d77db07fb11345818a58b359e2 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 02:15:00 +0100 Subject: [PATCH 079/160] client server changes and integration test (fails) --- kubi-udp/src/client.rs | 20 +++++++--- kubi-udp/src/server.rs | 14 +++++-- kubi-udp/tests/test.rs | 87 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 kubi-udp/tests/test.rs diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 91c2222..0174048 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -3,7 +3,7 @@ use std::{ net::{UdpSocket, SocketAddr}, time::{Instant, Duration}, marker::PhantomData, - collections::VecDeque, + collections::{VecDeque, vec_deque::Drain as DrainDeque}, }; use bincode::{Encode, Decode}; use crate::{ @@ -12,7 +12,7 @@ use crate::{ common::ClientId }; -#[derive(Default, Clone)] +#[derive(Default, Clone, Debug)] #[repr(u8)] pub enum DisconnectReason { #[default] @@ -35,9 +35,17 @@ pub struct ClientConfig { pub timeout: Duration, pub heartbeat_interval: Duration, } +impl Default for ClientConfig { + fn default() -> Self { + Self { + timeout: Duration::from_secs(5), + heartbeat_interval: Duration::from_secs(3), + } + } +} pub enum ClientEvent where T: Encode + Decode { - Connected, + Connected(ClientId), Disconnected(DisconnectReason), MessageReceived(T) } @@ -52,7 +60,7 @@ pub struct Client where S: Encode + Decode, R: Encode + Decode { client_id: Option, disconnect_reason: DisconnectReason, event_queue: VecDeque>, - _s: PhantomData<*const S>, + _s: PhantomData, } impl Client where S: Encode + Decode, R: Encode + Decode { pub fn new(addr: SocketAddr, config: ClientConfig) -> Result { @@ -156,7 +164,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { ServerPacket::Connected(client_id) => { self.client_id = Some(client_id); self.status = ClientStatus::Connected; - self.event_queue.push_back(ClientEvent::Connected); + self.event_queue.push_back(ClientEvent::Connected(client_id)); return Ok(()) }, ServerPacket::Disconnected(reason) => { @@ -180,7 +188,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { pub fn get_event(&mut self) -> Option> { self.event_queue.pop_front() } - pub fn process_events(&mut self) -> impl Iterator> + '_ { + pub fn process_events(&mut self) -> DrainDeque> { self.event_queue.drain(..) } } diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index f9a8322..d2d563c 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -2,7 +2,7 @@ use std::{ net::{UdpSocket, SocketAddr}, time::Instant, marker::PhantomData, - collections::VecDeque + collections::{VecDeque, vec_deque::Drain as DrainDeque} }; use anyhow::{Result, bail}; use bincode::{Encode, Decode}; @@ -105,8 +105,9 @@ impl Server where S: Encode + Decode, R: Encode + Decode { } Ok(()) } - pub fn send_message(&mut self) { - + pub fn send_message(&mut self, id: ClientId, message: S) -> anyhow::Result<()> { + self.send_packet(IdServerPacket(Some(id), ServerPacket::Data(message)))?; + Ok(()) } pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result { assert!(config.max_clients <= MAX_CLIENTS); @@ -183,4 +184,11 @@ impl Server where S: Encode + Decode, R: Encode + Decode { } Ok(()) } + + pub fn get_event(&mut self) -> Option> { + self.event_queue.pop_front() + } + pub fn process_events(&mut self) -> DrainDeque> { + self.event_queue.drain(..) + } } diff --git a/kubi-udp/tests/test.rs b/kubi-udp/tests/test.rs new file mode 100644 index 0000000..82d1bbd --- /dev/null +++ b/kubi-udp/tests/test.rs @@ -0,0 +1,87 @@ +use kubi_udp::{ + server::{Server, ServerConfig, ServerEvent}, + client::{Client, ClientConfig, ClientEvent}, +}; +use std::{thread, time::Duration}; + +const TEST_ADDR: &str = "127.0.0.1:12345"; + +type CtsMessage = u32; +type StcMessage = u64; + +const CTS_MSG: CtsMessage = 0xbeef_face; +const STC_MSG: StcMessage = 0xdead_beef_cafe_face; + +#[test] +fn test_connection() { + //Create server and client + let mut server: Server = Server::bind( + TEST_ADDR.parse().expect("Invalid TEST_ADDR"), + ServerConfig::default() + ).expect("Failed to create server"); + let mut client: Client = Client::new( + TEST_ADDR.parse().unwrap(), + ClientConfig::default() + ).expect("Failed to create client"); + + //Start server update thread + let server_handle = thread::spawn(move || { + let mut message_received = false; + loop { + server.update(); + let events: Vec<_> = server.process_events().collect(); + for event in events { + match event { + ServerEvent::Connected(id) => { + assert_eq!(id.get(), 1, "Unexpected client id"); + server.send_message(id, STC_MSG); + }, + ServerEvent::Disconnected(id) => { + assert!(message_received, "Client {id} disconnected from the server before sending the message") + }, + ServerEvent::MessageReceived { from, message } => { + assert_eq!(message, CTS_MSG, "Received message not equal"); + message_received = true; + break; + }, + _ => () + } + } + } + }); + + //Wait a bit + thread::sleep(Duration::from_secs(1)); + + //Connect client + client.connect().expect("Client connect failed"); + + //Start updating the client + let client_handle = thread::spawn(move || { + let mut message_received = false; + loop { + client.update(); + let events: Vec<_> = client.process_events().collect(); + for event in events { + match event { + ClientEvent::Connected(id) => { + assert_eq!(id.get(), 1, "Unexpected client id"); + client.send_message(CTS_MSG); + }, + ClientEvent::Disconnected(reason) => { + assert!(message_received, "Client lost connection to the server before sending the message with reason: {reason:?}") + }, + ClientEvent::MessageReceived(data) => { + assert_eq!(data, STC_MSG, "Received message not equal"); + message_received = true; + break; + }, + _ => () + } + } + } + }); + + client_handle.join().unwrap(); + server_handle.join().unwrap(); +} From 00f90156bdd20cbf304671aab8c389549dd9658c Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 02:33:48 +0100 Subject: [PATCH 080/160] test --- kubi-udp/Cargo.toml | 3 +++ kubi-udp/src/client.rs | 11 ++++++----- kubi-udp/tests/test.rs | 7 +++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/kubi-udp/Cargo.toml b/kubi-udp/Cargo.toml index 86da226..f08a674 100644 --- a/kubi-udp/Cargo.toml +++ b/kubi-udp/Cargo.toml @@ -11,3 +11,6 @@ anyhow = "1.0" hashbrown = "0.13" nohash-hasher = "0.2.0" log = "0.4" + +[dev-dependencies] +kubi-logging = { path = "../kubi-logging" } diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 0174048..049c01b 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -19,8 +19,7 @@ pub enum DisconnectReason { NotConnected, ClientDisconnected, KickedByServer(Option), - ClientTimeout, - ServerTimeout, + Timeout, } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -105,6 +104,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { pub fn connect(&mut self) -> Result<()> { + log::info!("client connect called"); if self.status != ClientStatus::Disconnected { bail!("Not Disconnected"); } @@ -139,7 +139,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { if self.timeout.elapsed() > self.config.timeout { log::warn!("Client timed out"); //We don't care if this packet actually gets sent because the server is likely dead - let _ = self.disconnect_inner(DisconnectReason::ClientDisconnected, false).map_err(|_| { + let _ = self.disconnect_inner(DisconnectReason::Timeout, false).map_err(|_| { log::warn!("Failed to send disconnect packet"); }); return Ok(()) @@ -162,15 +162,16 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.reset_timeout(); match packet { ServerPacket::Connected(client_id) => { + log::info!("client connected with id {client_id}"); self.client_id = Some(client_id); self.status = ClientStatus::Connected; self.event_queue.push_back(ClientEvent::Connected(client_id)); return Ok(()) }, ServerPacket::Disconnected(reason) => { + log::info!("client kicked: {reason}"); let reason = DisconnectReason::KickedByServer(Some(reason)); - //this should never fail but we're handling the error anyway - self.disconnect_inner(reason, true)?; + self.disconnect_inner(reason, true)?; //this should never fail but we're handling the error anyway return Ok(()) }, ServerPacket::Data(message) => { diff --git a/kubi-udp/tests/test.rs b/kubi-udp/tests/test.rs index 82d1bbd..d40da5e 100644 --- a/kubi-udp/tests/test.rs +++ b/kubi-udp/tests/test.rs @@ -4,7 +4,7 @@ use kubi_udp::{ }; use std::{thread, time::Duration}; -const TEST_ADDR: &str = "127.0.0.1:12345"; +const TEST_ADDR: &str = "127.0.0.1:22342"; type CtsMessage = u32; type StcMessage = u64; @@ -14,6 +14,9 @@ const STC_MSG: StcMessage = 0xdead_beef_cafe_face; #[test] fn test_connection() { + //Init logging + kubi_logging::init(); + //Create server and client let mut server: Server = Server::bind( TEST_ADDR.parse().expect("Invalid TEST_ADDR"), @@ -82,6 +85,6 @@ fn test_connection() { } }); - client_handle.join().unwrap(); server_handle.join().unwrap(); + client_handle.join().unwrap(); } From 7ecc4d5c249e275c3abd3e6151f279fff658d281 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 02:56:50 +0100 Subject: [PATCH 081/160] change things --- kubi-udp/src/client.rs | 18 ++++++++++-------- kubi-udp/src/server.rs | 17 +++++++++-------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 049c01b..c02bea1 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -3,7 +3,8 @@ use std::{ net::{UdpSocket, SocketAddr}, time::{Instant, Duration}, marker::PhantomData, - collections::{VecDeque, vec_deque::Drain as DrainDeque}, + collections::{VecDeque, vec_deque::Drain as DrainDeque}, + io::ErrorKind, }; use bincode::{Encode, Decode}; use crate::{ @@ -151,13 +152,13 @@ impl Client where S: Encode + Decode, R: Encode + Decode { } //receive let mut buf = Vec::new(); - loop { - if self.socket.recv(&mut buf).is_ok() { + match self.socket.recv(&mut buf) { + Ok(_) => { //TODO check the first byte of the raw data instead of decoding? let (packet, _): (IdServerPacket, _) = bincode::decode_from_slice(&buf, BINCODE_CONFIG)?; let IdServerPacket(user_id, packet) = packet; if self.client_id.map(|x| Some(x) != user_id).unwrap_or_default() { - continue + return Ok(()) } self.reset_timeout(); match packet { @@ -178,10 +179,11 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.event_queue.push_back(ClientEvent::MessageReceived(message)); } } - } else { - break - } - buf.clear(); + }, + Err(error) if error.kind() != ErrorKind::WouldBlock => { + return Err(error.into()); + }, + _ => (), } Ok(()) } diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index d2d563c..64bc97a 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -2,7 +2,8 @@ use std::{ net::{UdpSocket, SocketAddr}, time::Instant, marker::PhantomData, - collections::{VecDeque, vec_deque::Drain as DrainDeque} + collections::{VecDeque, vec_deque::Drain as DrainDeque}, + io::ErrorKind }; use anyhow::{Result, bail}; use bincode::{Encode, Decode}; @@ -113,7 +114,6 @@ impl Server where S: Encode + Decode, R: Encode + Decode { assert!(config.max_clients <= MAX_CLIENTS); let socket = UdpSocket::bind(addr)?; socket.set_nonblocking(true)?; - //socket.set_broadcast(true)?; Ok(Self { config, socket, @@ -125,8 +125,8 @@ impl Server where S: Encode + Decode, R: Encode + Decode { pub fn update(&mut self) -> Result<()> { //TODO client timeout let mut buf = Vec::new(); - loop { - if let Ok((_, addr)) = self.socket.recv_from(&mut buf) { + match self.socket.recv_from(&mut buf) { + Ok((_, addr)) => { if let Ok(packet) = bincode::decode_from_slice(&buf, BINCODE_CONFIG) { let (packet, _): (IdClientPacket, _) = packet; let IdClientPacket(id, packet) = packet; @@ -177,10 +177,11 @@ impl Server where S: Encode + Decode, R: Encode + Decode { } else { bail!("Corrupted packet received"); } - } else { - break - } - buf.clear() + }, + Err(error) if error.kind() != ErrorKind::WouldBlock => { + return Err(error.into()); + }, + _ => (), } Ok(()) } From 907e3164d73ec25e91b2f0d542b7fac327496e2a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 03:15:31 +0100 Subject: [PATCH 082/160] oops --- kubi-udp/src/client.rs | 2 +- kubi-udp/tests/test.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index c02bea1..75ddf2f 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -64,7 +64,7 @@ pub struct Client where S: Encode + Decode, R: Encode + Decode { } impl Client where S: Encode + Decode, R: Encode + Decode { pub fn new(addr: SocketAddr, config: ClientConfig) -> Result { - let bind_addr: SocketAddr = "127.0.0.1:0".parse().unwrap(); + let bind_addr: SocketAddr = "0.0.0.0:0".parse().unwrap(); let socket = UdpSocket::bind(bind_addr)?; socket.set_nonblocking(true)?; Ok(Self { diff --git a/kubi-udp/tests/test.rs b/kubi-udp/tests/test.rs index d40da5e..87aa2a3 100644 --- a/kubi-udp/tests/test.rs +++ b/kubi-udp/tests/test.rs @@ -16,7 +16,7 @@ const STC_MSG: StcMessage = 0xdead_beef_cafe_face; fn test_connection() { //Init logging kubi_logging::init(); - + //Create server and client let mut server: Server = Server::bind( TEST_ADDR.parse().expect("Invalid TEST_ADDR"), @@ -31,13 +31,13 @@ fn test_connection() { let server_handle = thread::spawn(move || { let mut message_received = false; loop { - server.update(); + server.update().unwrap(); let events: Vec<_> = server.process_events().collect(); for event in events { match event { ServerEvent::Connected(id) => { assert_eq!(id.get(), 1, "Unexpected client id"); - server.send_message(id, STC_MSG); + server.send_message(id, STC_MSG).unwrap(); }, ServerEvent::Disconnected(id) => { assert!(message_received, "Client {id} disconnected from the server before sending the message") @@ -63,13 +63,13 @@ fn test_connection() { let client_handle = thread::spawn(move || { let mut message_received = false; loop { - client.update(); + client.update().unwrap(); let events: Vec<_> = client.process_events().collect(); for event in events { match event { ClientEvent::Connected(id) => { assert_eq!(id.get(), 1, "Unexpected client id"); - client.send_message(CTS_MSG); + client.send_message(CTS_MSG).unwrap(); }, ClientEvent::Disconnected(reason) => { assert!(message_received, "Client lost connection to the server before sending the message with reason: {reason:?}") From 70aaba01b0f37b1540d6f3b05a176730260d4433 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 03:22:42 +0100 Subject: [PATCH 083/160] fix --- kubi-udp/src/client.rs | 6 +++--- kubi-udp/src/server.rs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 75ddf2f..31f5d17 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -151,11 +151,11 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.last_heartbeat = Instant::now(); } //receive - let mut buf = Vec::new(); + let mut buf = [0; u16::MAX as usize]; match self.socket.recv(&mut buf) { - Ok(_) => { + Ok(length) => { //TODO check the first byte of the raw data instead of decoding? - let (packet, _): (IdServerPacket, _) = bincode::decode_from_slice(&buf, BINCODE_CONFIG)?; + let (packet, _): (IdServerPacket, _) = bincode::decode_from_slice(&buf[..length], BINCODE_CONFIG)?; let IdServerPacket(user_id, packet) = packet; if self.client_id.map(|x| Some(x) != user_id).unwrap_or_default() { return Ok(()) diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 64bc97a..f358c6e 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -70,7 +70,7 @@ impl Server where S: Encode + Decode, R: Encode + Decode { fn add_client(&mut self, addr: SocketAddr) -> Result { let Some(id) = (1..=self.config.max_clients) .map(|x| ClientId::new(x as _).unwrap()) - .find(|i| self.clients.contains_key(i)) else { + .find(|i| !self.clients.contains_key(i)) else { bail!("Server full"); }; if self.clients.iter().any(|x| x.1.addr == addr) { @@ -124,10 +124,10 @@ impl Server where S: Encode + Decode, R: Encode + Decode { } pub fn update(&mut self) -> Result<()> { //TODO client timeout - let mut buf = Vec::new(); + let mut buf = [0; u16::MAX as usize]; match self.socket.recv_from(&mut buf) { - Ok((_, addr)) => { - if let Ok(packet) = bincode::decode_from_slice(&buf, BINCODE_CONFIG) { + Ok((len, addr)) => { + if let Ok(packet) = bincode::decode_from_slice(&buf[..len], BINCODE_CONFIG) { let (packet, _): (IdClientPacket, _) = packet; let IdClientPacket(id, packet) = packet; match id { From 6c27d63bdf820248416547b94ed4e8affb98a739 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 03:38:18 +0100 Subject: [PATCH 084/160] it passes --- kubi-udp/src/server.rs | 4 +++- kubi-udp/tests/test.rs | 11 +++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index f358c6e..0296317 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -81,7 +81,6 @@ impl Server where S: Encode + Decode, R: Encode + Decode { addr, timeout: Instant::now(), }); - log::info!("Client with id {id} connected"); Ok(id) } fn disconnect_client_inner(&mut self, id: ClientId, reason: String) -> Result<()> { @@ -143,6 +142,7 @@ impl Server where S: Encode + Decode, R: Encode + Decode { }); } ClientPacket::Disconnect => { + log::info!("Client {id} disconnected"); self.event_queue.push_back(ServerEvent::Disconnected(id)); self.disconnect_client_inner(id, "Disconnected".into())?; }, @@ -157,6 +157,7 @@ impl Server where S: Encode + Decode, R: Encode + Decode { ClientPacket::Connect => { match self.add_client(addr) { Ok(id) => { + log::info!("Client with id {id} connected"); self.event_queue.push_back(ServerEvent::Connected(id)); self.send_to_addr(addr, IdServerPacket(None, ServerPacket::Connected(id) @@ -164,6 +165,7 @@ impl Server where S: Encode + Decode, R: Encode + Decode { }, Err(error) => { let reason = error.to_string(); + log::error!("Client connection failed: {reason}"); self.send_to_addr(addr, IdServerPacket( None, ServerPacket::Disconnected(reason) ))?; diff --git a/kubi-udp/tests/test.rs b/kubi-udp/tests/test.rs index 87aa2a3..6de54d2 100644 --- a/kubi-udp/tests/test.rs +++ b/kubi-udp/tests/test.rs @@ -40,12 +40,13 @@ fn test_connection() { server.send_message(id, STC_MSG).unwrap(); }, ServerEvent::Disconnected(id) => { - assert!(message_received, "Client {id} disconnected from the server before sending the message") + assert!(message_received, "Client {id} disconnected from the server before sending the message"); + return; }, ServerEvent::MessageReceived { from, message } => { + log::info!("server received message"); assert_eq!(message, CTS_MSG, "Received message not equal"); message_received = true; - break; }, _ => () } @@ -72,12 +73,14 @@ fn test_connection() { client.send_message(CTS_MSG).unwrap(); }, ClientEvent::Disconnected(reason) => { - assert!(message_received, "Client lost connection to the server before sending the message with reason: {reason:?}") + assert!(message_received, "Client lost connection to the server before sending the message with reason: {reason:?}"); + return; }, ClientEvent::MessageReceived(data) => { + log::info!("client received message"); assert_eq!(data, STC_MSG, "Received message not equal"); message_received = true; - break; + client.disconnect(); }, _ => () } From 05444bd4b82727710930bc3fdcd3c12aa0766ffd Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 04:04:48 +0100 Subject: [PATCH 085/160] basic networking --- kubi-server/src/client.rs | 12 ------ kubi-shared/src/networking.rs | 1 + kubi-shared/src/networking/state.rs | 14 +++++++ kubi/Cargo.toml | 2 +- kubi/src/networking.rs | 59 ++++++++++++++++++++++++++++- 5 files changed, 73 insertions(+), 15 deletions(-) create mode 100644 kubi-shared/src/networking/state.rs diff --git a/kubi-server/src/client.rs b/kubi-server/src/client.rs index 2508fa1..23587b7 100644 --- a/kubi-server/src/client.rs +++ b/kubi-server/src/client.rs @@ -6,18 +6,6 @@ use kubi_udp::{ClientId, ClientIdRepr}; #[derive(Component)] pub struct Client(ClientId); - -// disconnected => connect => join => load => ingame -#[derive(Component)] -pub enum ClientJoinState { - /// Client has connected to the game, but haven't authenticated yet - Connected, - /// Client has joined the game, but haven't loaded the world yet - Joined, - /// Client is currently ingame - InGame, -} - pub struct ClientMap(HashMap>); impl ClientMap { pub fn new() -> Self { diff --git a/kubi-shared/src/networking.rs b/kubi-shared/src/networking.rs index ba63992..4945d0c 100644 --- a/kubi-shared/src/networking.rs +++ b/kubi-shared/src/networking.rs @@ -1 +1,2 @@ pub mod messages; +pub mod state; diff --git a/kubi-shared/src/networking/state.rs b/kubi-shared/src/networking/state.rs new file mode 100644 index 0000000..dbed8e1 --- /dev/null +++ b/kubi-shared/src/networking/state.rs @@ -0,0 +1,14 @@ +use shipyard::{Unique, Component}; + +// disconnected => connect => join => load => ingame +#[derive(Unique, Component)] +pub enum ClientJoinState { + /// Not connected yet + Disconnected, + /// Client has connected to the game, but hasn't authenticated yet + Connected, + /// Client has joined the game, but haven't loaded the world yet + Joined, + /// Client is currently ingame + InGame, +} diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index c88d405..90d9250 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] kubi-shared = { path = "../kubi-shared" } -kubi-udp = { path = "../kubi-udp", optional = true } +kubi-udp = { path = "../kubi-udp" } kubi-logging = { path = "../kubi-logging" } log = "*" glium = "0.32" diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 3a3bea4..39c9989 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -1,6 +1,10 @@ +use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, WorkloadModificator}; use std::net::SocketAddr; - -use shipyard::Unique; +use kubi_udp::client::{Client, ClientConfig}; +use kubi_shared::networking::{ + messages::{ClientToServerMessage, ServerToClientMessage}, + state::ClientJoinState +}; #[derive(Unique, Clone, Copy, PartialEq, Eq)] pub enum GameType { @@ -10,3 +14,54 @@ pub enum GameType { #[derive(Unique, Clone, Copy, PartialEq, Eq)] pub struct ServerAddress(pub SocketAddr); + +#[derive(Unique)] +pub struct UdpClient(pub Client); + +pub fn create_client( + storages: AllStoragesView +) { + let address = storages.borrow::>().unwrap(); + storages.add_unique(UdpClient(Client::new( + address.0, + ClientConfig::default() + ).unwrap())); + storages.add_unique(ClientJoinState::Disconnected); +} + +pub fn client_connect( + mut client: UniqueViewMut +) { + client.0.connect().unwrap(); +} + +pub fn update_client( + mut client: UniqueViewMut +) { + client.0.update().unwrap(); +} + +pub fn init_networking() -> Workload { + ( + create_client, + client_connect, + ).into_workload().run_if(is_multiplayer) +} + +pub fn update_networking() -> Workload { + ( + update_client, + ).into_workload().run_if(is_multiplayer) +} + +pub fn is_multiplayer( + game_type: UniqueView +) -> bool { + *game_type == GameType::Muliplayer +} + +pub fn is_singleplayer( + game_type: UniqueView +) -> bool { + *game_type == GameType::Singleplayer +} From bcd3066c95de64159b00c838ccac7ec0d0cca965 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 18:52:17 +0100 Subject: [PATCH 086/160] todo --- kubi/src/networking.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 39c9989..136cd49 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -35,10 +35,13 @@ pub fn client_connect( client.0.connect().unwrap(); } -pub fn update_client( - mut client: UniqueViewMut +pub fn update_client_and_get_events( + mut client: UniqueViewMut, ) { client.0.update().unwrap(); + for event in client.0.process_events() { + todo!() + } } pub fn init_networking() -> Workload { @@ -50,7 +53,7 @@ pub fn init_networking() -> Workload { pub fn update_networking() -> Workload { ( - update_client, + update_client_and_get_events, ).into_workload().run_if(is_multiplayer) } From 8758938e7e9ded24854280808d9227237ebb2c74 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 20:37:06 +0100 Subject: [PATCH 087/160] client networking calls --- kubi-udp/src/client.rs | 88 +++++++++++++++--------- kubi-udp/src/server.rs | 147 ++++++++++++++++++++++------------------- kubi/src/main.rs | 10 ++- kubi/src/networking.rs | 44 ++++++++---- 4 files changed, 173 insertions(+), 116 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 31f5d17..07ab09c 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -51,7 +51,7 @@ pub enum ClientEvent where T: Encode + Decode { } pub struct Client where S: Encode + Decode, R: Encode + Decode { - pub config: ClientConfig, + config: ClientConfig, addr: SocketAddr, socket: UdpSocket, status: ClientStatus, @@ -125,6 +125,28 @@ impl Client where S: Encode + Decode, R: Encode + Decode { Ok(()) } + pub fn get_status(&self) -> ClientStatus { + self.status + } + + pub fn is_connected(&self) -> bool { + self.status == ClientStatus::Connected + } + + pub fn is_connecting(&self) -> bool { + self.status == ClientStatus::Connecting + } + + pub fn is_disconnected(&self) -> bool { + self.status == ClientStatus::Disconnected + } + + //Return true if the client has not made any connection attempts yet + pub fn has_not_made_connection_attempts(&self) -> bool { + matches!(self.status, ClientStatus::Disconnected) && + matches!(self.disconnect_reason, DisconnectReason::NotConnected) + } + pub fn send_message(&self, message: S) -> Result<()> { if self.status != ClientStatus::Connected { bail!("Not Connected"); @@ -152,43 +174,45 @@ impl Client where S: Encode + Decode, R: Encode + Decode { } //receive let mut buf = [0; u16::MAX as usize]; - match self.socket.recv(&mut buf) { - Ok(length) => { - //TODO check the first byte of the raw data instead of decoding? - let (packet, _): (IdServerPacket, _) = bincode::decode_from_slice(&buf[..length], BINCODE_CONFIG)?; - let IdServerPacket(user_id, packet) = packet; - if self.client_id.map(|x| Some(x) != user_id).unwrap_or_default() { - return Ok(()) - } - self.reset_timeout(); - match packet { - ServerPacket::Connected(client_id) => { - log::info!("client connected with id {client_id}"); - self.client_id = Some(client_id); - self.status = ClientStatus::Connected; - self.event_queue.push_back(ClientEvent::Connected(client_id)); + loop { + match self.socket.recv(&mut buf) { + Ok(length) => { + //TODO check the first byte of the raw data instead of decoding? + let (packet, _): (IdServerPacket, _) = bincode::decode_from_slice(&buf[..length], BINCODE_CONFIG)?; + let IdServerPacket(user_id, packet) = packet; + if self.client_id.map(|x| Some(x) != user_id).unwrap_or_default() { return Ok(()) - }, - ServerPacket::Disconnected(reason) => { - log::info!("client kicked: {reason}"); - let reason = DisconnectReason::KickedByServer(Some(reason)); - self.disconnect_inner(reason, true)?; //this should never fail but we're handling the error anyway - return Ok(()) - }, - ServerPacket::Data(message) => { - self.event_queue.push_back(ClientEvent::MessageReceived(message)); } - } - }, - Err(error) if error.kind() != ErrorKind::WouldBlock => { - return Err(error.into()); - }, - _ => (), + self.reset_timeout(); + match packet { + ServerPacket::Connected(client_id) => { + log::info!("client connected with id {client_id}"); + self.client_id = Some(client_id); + self.status = ClientStatus::Connected; + self.event_queue.push_back(ClientEvent::Connected(client_id)); + return Ok(()) + }, + ServerPacket::Disconnected(reason) => { + log::info!("client kicked: {reason}"); + let reason = DisconnectReason::KickedByServer(Some(reason)); + self.disconnect_inner(reason, true)?; //this should never fail but we're handling the error anyway + return Ok(()) + }, + ServerPacket::Data(message) => { + self.event_queue.push_back(ClientEvent::MessageReceived(message)); + } + } + }, + Err(error) if error.kind() != ErrorKind::WouldBlock => { + return Err(error.into()); + }, + _ => break, + } } Ok(()) } - pub fn get_event(&mut self) -> Option> { + pub fn pop_event(&mut self) -> Option> { self.event_queue.pop_front() } pub fn process_events(&mut self) -> DrainDeque> { diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 0296317..5d135a0 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -52,11 +52,25 @@ pub struct Server where S: Encode + Decode, R: Encode + Decode { _s: PhantomData, } impl Server where S: Encode + Decode, R: Encode + Decode { + pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result { + assert!(config.max_clients <= MAX_CLIENTS); + let socket = UdpSocket::bind(addr)?; + socket.set_nonblocking(true)?; + Ok(Self { + config, + socket, + clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()), + event_queue: VecDeque::new(), + _s: PhantomData, + }) + } + fn send_to_addr(&self, addr: SocketAddr, packet: IdServerPacket) -> Result<()> { let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; self.socket.send_to(&bytes, addr)?; Ok(()) } + fn send_packet(&self, packet: IdServerPacket) -> Result<()> { let Some(id) = packet.0 else { bail!("send_to_client call without id") @@ -67,6 +81,7 @@ impl Server where S: Encode + Decode, R: Encode + Decode { self.send_to_addr(client.addr, packet)?; Ok(()) } + fn add_client(&mut self, addr: SocketAddr) -> Result { let Some(id) = (1..=self.config.max_clients) .map(|x| ClientId::new(x as _).unwrap()) @@ -83,6 +98,7 @@ impl Server where S: Encode + Decode, R: Encode + Decode { }); Ok(id) } + fn disconnect_client_inner(&mut self, id: ClientId, reason: String) -> Result<()> { let result = self.send_packet(IdServerPacket( Some(id), ServerPacket::Disconnected(reason) @@ -98,6 +114,7 @@ impl Server where S: Encode + Decode, R: Encode + Decode { self.disconnect_client_inner(id, reason)?; Ok(()) } + pub fn shutdown(mut self) -> Result<()> { let clients = self.clients.keys().copied().collect::>(); for id in clients { @@ -105,90 +122,82 @@ impl Server where S: Encode + Decode, R: Encode + Decode { } Ok(()) } + pub fn send_message(&mut self, id: ClientId, message: S) -> anyhow::Result<()> { self.send_packet(IdServerPacket(Some(id), ServerPacket::Data(message)))?; Ok(()) } - pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result { - assert!(config.max_clients <= MAX_CLIENTS); - let socket = UdpSocket::bind(addr)?; - socket.set_nonblocking(true)?; - Ok(Self { - config, - socket, - clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()), - event_queue: VecDeque::new(), - _s: PhantomData, - }) - } + pub fn update(&mut self) -> Result<()> { //TODO client timeout let mut buf = [0; u16::MAX as usize]; - match self.socket.recv_from(&mut buf) { - Ok((len, addr)) => { - if let Ok(packet) = bincode::decode_from_slice(&buf[..len], BINCODE_CONFIG) { - let (packet, _): (IdClientPacket, _) = packet; - let IdClientPacket(id, packet) = packet; - match id { - Some(id) => { - if !self.clients.contains_key(&id) { - bail!("Client with id {id} doesn't exist"); - }; - match packet { - ClientPacket::Data(data) => { - self.event_queue.push_back(ServerEvent::MessageReceived { - from: id, - message: data, - }); - } - ClientPacket::Disconnect => { - log::info!("Client {id} disconnected"); - self.event_queue.push_back(ServerEvent::Disconnected(id)); - self.disconnect_client_inner(id, "Disconnected".into())?; - }, - ClientPacket::Heartbeat => { - self.clients.get_mut(&id).unwrap().timeout = Instant::now() - }, - ClientPacket::Connect => bail!("Client already connected"), - } - }, - None => { - match packet { - ClientPacket::Connect => { - match self.add_client(addr) { - Ok(id) => { - log::info!("Client with id {id} connected"); - self.event_queue.push_back(ServerEvent::Connected(id)); - self.send_to_addr(addr, - IdServerPacket(None, ServerPacket::Connected(id) - ))?; - }, - Err(error) => { - let reason = error.to_string(); - log::error!("Client connection failed: {reason}"); - self.send_to_addr(addr, IdServerPacket( - None, ServerPacket::Disconnected(reason) - ))?; - } + loop { + match self.socket.recv_from(&mut buf) { + Ok((len, addr)) => { + if let Ok(packet) = bincode::decode_from_slice(&buf[..len], BINCODE_CONFIG) { + let (packet, _): (IdClientPacket, _) = packet; + let IdClientPacket(id, packet) = packet; + match id { + Some(id) => { + if !self.clients.contains_key(&id) { + bail!("Client with id {id} doesn't exist"); + }; + match packet { + ClientPacket::Data(data) => { + self.event_queue.push_back(ServerEvent::MessageReceived { + from: id, + message: data, + }); } - }, - _ => bail!("Invalid packet type for non-id packet") + ClientPacket::Disconnect => { + log::info!("Client {id} disconnected"); + self.event_queue.push_back(ServerEvent::Disconnected(id)); + self.disconnect_client_inner(id, "Disconnected".into())?; + }, + ClientPacket::Heartbeat => { + self.clients.get_mut(&id).unwrap().timeout = Instant::now() + }, + ClientPacket::Connect => bail!("Client already connected"), + } + }, + None => { + match packet { + ClientPacket::Connect => { + match self.add_client(addr) { + Ok(id) => { + log::info!("Client with id {id} connected"); + self.event_queue.push_back(ServerEvent::Connected(id)); + self.send_to_addr(addr, + IdServerPacket(None, ServerPacket::Connected(id) + ))?; + }, + Err(error) => { + let reason = error.to_string(); + log::error!("Client connection failed: {reason}"); + self.send_to_addr(addr, IdServerPacket( + None, ServerPacket::Disconnected(reason) + ))?; + } + } + }, + _ => bail!("Invalid packet type for non-id packet") + } } } + } else { + bail!("Corrupted packet received"); } - } else { - bail!("Corrupted packet received"); - } - }, - Err(error) if error.kind() != ErrorKind::WouldBlock => { - return Err(error.into()); - }, - _ => (), + }, + Err(error) if error.kind() != ErrorKind::WouldBlock => { + return Err(error.into()); + }, + _ => break, + } } Ok(()) } - pub fn get_event(&mut self) -> Option> { + pub fn pop_event(&mut self) -> Option> { self.event_queue.pop_front() } pub fn process_events(&mut self) -> DrainDeque> { diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 924d481..3ddf83d 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -63,16 +63,19 @@ use rendering::{ RenderTarget, BackgroundColor, clear_background, + init_window_size, + update_window_size, primitives::init_primitives, selection_box::render_selection_box, world::draw_world, - world::draw_current_chunk_border, init_window_size, update_window_size, + world::draw_current_chunk_border, }; use block_placement::block_placement_system; use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state}; +use networking::{update_networking, is_multiplayer}; use init::initialize_from_args; use gui::{render_gui, init_gui, update_gui}; use loading_screen::update_loading_screen; @@ -102,6 +105,9 @@ fn update() -> Workload { update_cursor_lock_state, process_inputs, exit_on_esc, + ( + update_networking + ).into_workload().run_if(is_multiplayer), ( update_loading_screen, ).into_workload().run_if(is_loading), @@ -114,8 +120,8 @@ fn update() -> Workload { update_raycasts, block_placement_system, apply_queued_blocks, + compute_cameras, ).into_workload().run_if(is_ingame), - compute_cameras, update_gui, update_state, ).into_workload() diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 136cd49..3254bc4 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -1,11 +1,13 @@ -use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, WorkloadModificator}; +use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, WorkloadModificator, EntitiesView, EntitiesViewMut, Component, ViewMut, SystemModificator}; use std::net::SocketAddr; -use kubi_udp::client::{Client, ClientConfig}; +use kubi_udp::client::{Client, ClientConfig, ClientEvent}; use kubi_shared::networking::{ messages::{ClientToServerMessage, ServerToClientMessage}, state::ClientJoinState }; +use crate::events::EventComponent; + #[derive(Unique, Clone, Copy, PartialEq, Eq)] pub enum GameType { Singleplayer, @@ -18,6 +20,9 @@ pub struct ServerAddress(pub SocketAddr); #[derive(Unique)] pub struct UdpClient(pub Client); +#[derive(Component)] +pub struct NetworkEvent(pub ClientEvent); + pub fn create_client( storages: AllStoragesView ) { @@ -29,34 +34,47 @@ pub fn create_client( storages.add_unique(ClientJoinState::Disconnected); } -pub fn client_connect( +pub fn connect_client( mut client: UniqueViewMut ) { client.0.connect().unwrap(); } -pub fn update_client_and_get_events( +pub fn update_client( mut client: UniqueViewMut, ) { client.0.update().unwrap(); - for event in client.0.process_events() { - todo!() - } } -pub fn init_networking() -> Workload { - ( - create_client, - client_connect, - ).into_workload().run_if(is_multiplayer) +pub fn insert_client_events( + mut client: UniqueViewMut, + mut entities: EntitiesViewMut, + mut events: ViewMut, + mut network_events: ViewMut, +) { + entities.bulk_add_entity(( + &mut events, + &mut network_events, + ), client.0.process_events().map(|event| { + (EventComponent, NetworkEvent(event)) + })); } pub fn update_networking() -> Workload { ( - update_client_and_get_events, + create_client.run_if_missing_unique::(), + connect_client.run_if(client_needs_connect_call), + update_client, + insert_client_events, ).into_workload().run_if(is_multiplayer) } +fn client_needs_connect_call( + client: UniqueView, +) -> bool { + client.0.has_not_made_connection_attempts() +} + pub fn is_multiplayer( game_type: UniqueView ) -> bool { From e0872b331f946d535dadaddf8133740f064eea78 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 21:31:21 +0100 Subject: [PATCH 088/160] ignore io errors on server --- kubi-logging/src/lib.rs | 10 ++++++++-- kubi-udp/src/server.rs | 3 ++- kubi/src/main.rs | 3 +++ kubi/src/networking.rs | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/kubi-logging/src/lib.rs b/kubi-logging/src/lib.rs index 84505f0..7a4c922 100644 --- a/kubi-logging/src/lib.rs +++ b/kubi-logging/src/lib.rs @@ -20,6 +20,9 @@ pub fn init() { _ => Color::Blue }).set_bold(true); + let mut bold_style = buf.style(); + bold_style.set_bold(true); + let mut location_style = buf.style(); location_style.set_bold(true); location_style.set_dimmed(true); @@ -27,9 +30,11 @@ pub fn init() { let mut location_line_style = buf.style(); location_line_style.set_dimmed(true); + let text = format!("{}", record.args()); + writeln!( buf, - "{} {:<50}\t{}{}{}", + "{} {:<50}\t{}{}{}{}", level_style.value(match record.level() { Level::Error => "[e]", Level::Warn => "[w]", @@ -37,7 +42,8 @@ pub fn init() { Level::Debug => "[d]", Level::Trace => "[t]", }), - format!("{}", record.args()), + text, + bold_style.value((text.len() > 50).then_some("\n ╰─ ").unwrap_or_default()), location_style.value(record.target()), location_line_style.value(" :"), location_line_style.value(record.line().unwrap_or(0)) diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 5d135a0..05cd01e 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -189,7 +189,8 @@ impl Server where S: Encode + Decode, R: Encode + Decode { } }, Err(error) if error.kind() != ErrorKind::WouldBlock => { - return Err(error.into()); + log::warn!("IO error {}", error); + // return Err(error.into()); }, _ => break, } diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 3ddf83d..64de54c 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -152,6 +152,9 @@ fn attach_console() { fn main() { //Attach console on release builds on windows #[cfg(all(windows, not(debug_assertions)))] attach_console(); + + //Print version + println!("{:─^54}", format!("[ ▄▀ Kubi client v. {} ]", env!("CARGO_PKG_VERSION"))); //Init env_logger kubi_logging::init(); diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 3254bc4..4b5a8ff 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -66,7 +66,7 @@ pub fn update_networking() -> Workload { connect_client.run_if(client_needs_connect_call), update_client, insert_client_events, - ).into_workload().run_if(is_multiplayer) + ).into_workload() } fn client_needs_connect_call( From d28069e9e6faf7393f65ec21b2814e0f56820dac Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 21:40:42 +0100 Subject: [PATCH 089/160] replace `.into_workload().run_if()` with `.run_if()` --- kubi/src/loading_screen.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kubi/src/loading_screen.rs b/kubi/src/loading_screen.rs index 585a009..02242aa 100644 --- a/kubi/src/loading_screen.rs +++ b/kubi/src/loading_screen.rs @@ -1,4 +1,4 @@ -use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload, WorkloadModificator, EntityId, Unique, AllStoragesViewMut, ViewMut, View, IntoIter, Get}; +use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload, EntityId, Unique, AllStoragesViewMut, ViewMut, Get, SystemModificator}; use glam::{Mat3, vec2}; use crate::{ world::ChunkStorage, @@ -82,10 +82,10 @@ fn despawn_loading_screen_if_switching_state( pub fn update_loading_screen() -> Workload { ( - spawn_loading_screen.into_workload().run_if_missing_unique::(), - resize_progress_bar.into_workload().run_if(if_resized), + spawn_loading_screen.run_if_missing_unique::(), + resize_progress_bar.run_if(if_resized), update_progress_bar_progress, switch_to_ingame_if_loaded, - despawn_loading_screen_if_switching_state.into_workload().run_if(is_changing_state), + despawn_loading_screen_if_switching_state.run_if(is_changing_state), ).into_workload() } From eabddf3019ce53bc526ccbc0be509bd13df2471f Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 21:42:29 +0100 Subject: [PATCH 090/160] inline client functions --- kubi-udp/src/client.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 07ab09c..7667e16 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -63,6 +63,7 @@ pub struct Client where S: Encode + Decode, R: Encode + Decode { _s: PhantomData, } impl Client where S: Encode + Decode, R: Encode + Decode { + #[inline] pub fn new(addr: SocketAddr, config: ClientConfig) -> Result { let bind_addr: SocketAddr = "0.0.0.0:0".parse().unwrap(); let socket = UdpSocket::bind(bind_addr)?; @@ -103,7 +104,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.timeout = Instant::now(); } - + #[inline] pub fn connect(&mut self) -> Result<()> { log::info!("client connect called"); if self.status != ClientStatus::Disconnected { @@ -117,6 +118,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { Ok(()) } + #[inline] pub fn disconnect(&mut self) -> Result<()> { if self.status != ClientStatus::Connected { bail!("Not Connected"); @@ -125,28 +127,34 @@ impl Client where S: Encode + Decode, R: Encode + Decode { Ok(()) } + #[inline] pub fn get_status(&self) -> ClientStatus { self.status } + #[inline] pub fn is_connected(&self) -> bool { self.status == ClientStatus::Connected } + #[inline] pub fn is_connecting(&self) -> bool { self.status == ClientStatus::Connecting } + #[inline] pub fn is_disconnected(&self) -> bool { self.status == ClientStatus::Disconnected } //Return true if the client has not made any connection attempts yet + #[inline] pub fn has_not_made_connection_attempts(&self) -> bool { matches!(self.status, ClientStatus::Disconnected) && matches!(self.disconnect_reason, DisconnectReason::NotConnected) } + #[inline] pub fn send_message(&self, message: S) -> Result<()> { if self.status != ClientStatus::Connected { bail!("Not Connected"); @@ -155,6 +163,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { Ok(()) } + #[inline] pub fn update(&mut self) -> Result<()> { // , callback: fn(ClientEvent) -> Result<()> if self.status == ClientStatus::Disconnected { return Ok(()) @@ -212,9 +221,12 @@ impl Client where S: Encode + Decode, R: Encode + Decode { Ok(()) } + #[inline] pub fn pop_event(&mut self) -> Option> { self.event_queue.pop_front() } + + #[inline] pub fn process_events(&mut self) -> DrainDeque> { self.event_queue.drain(..) } From bf7fc475e2c8d742fc6a41d5b1a6bea96698efac Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 21:50:24 +0100 Subject: [PATCH 091/160] fix camera updates --- kubi/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 64de54c..4cdfce5 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -120,8 +120,8 @@ fn update() -> Workload { update_raycasts, block_placement_system, apply_queued_blocks, - compute_cameras, ).into_workload().run_if(is_ingame), + compute_cameras, update_gui, update_state, ).into_workload() From b8447bc121ebe7b1d5f1f1313da45c5b11d9a958 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 22:15:09 +0100 Subject: [PATCH 092/160] what the fuck --- kubi/src/networking.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 4b5a8ff..65fd538 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -37,7 +37,9 @@ pub fn create_client( pub fn connect_client( mut client: UniqueViewMut ) { - client.0.connect().unwrap(); + if !client.0.has_not_made_connection_attempts() { + client.0.connect().unwrap(); + } } pub fn update_client( @@ -63,18 +65,12 @@ pub fn insert_client_events( pub fn update_networking() -> Workload { ( create_client.run_if_missing_unique::(), - connect_client.run_if(client_needs_connect_call), + connect_client, update_client, insert_client_events, ).into_workload() } -fn client_needs_connect_call( - client: UniqueView, -) -> bool { - client.0.has_not_made_connection_attempts() -} - pub fn is_multiplayer( game_type: UniqueView ) -> bool { From 80ef55c8b34fd540b46f5f1e693fd403faa56516 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 22:28:44 +0100 Subject: [PATCH 093/160] better error handling on client --- kubi-udp/src/client.rs | 12 +++++++++++- kubi-udp/src/server.rs | 2 +- kubi/src/networking.rs | 4 +++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 7667e16..be9d6e1 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -21,6 +21,7 @@ pub enum DisconnectReason { ClientDisconnected, KickedByServer(Option), Timeout, + ConnectionReset, } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -213,7 +214,16 @@ impl Client where S: Encode + Decode, R: Encode + Decode { } }, Err(error) if error.kind() != ErrorKind::WouldBlock => { - return Err(error.into()); + match error.kind() { + ErrorKind::ConnectionReset => { + log::error!("Connection interrupted"); + self.disconnect_inner(DisconnectReason::ConnectionReset, true)?; + }, + _ => { + log::error!("IO error {error}"); + return Err(error.into()); + }, + } }, _ => break, } diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 05cd01e..b15a185 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -189,7 +189,7 @@ impl Server where S: Encode + Decode, R: Encode + Decode { } }, Err(error) if error.kind() != ErrorKind::WouldBlock => { - log::warn!("IO error {}", error); + log::error!("IO error {}", error); // return Err(error.into()); }, _ => break, diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 65fd538..16450b0 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -26,6 +26,7 @@ pub struct NetworkEvent(pub ClientEvent); pub fn create_client( storages: AllStoragesView ) { + log::info!("Creating client"); let address = storages.borrow::>().unwrap(); storages.add_unique(UdpClient(Client::new( address.0, @@ -37,7 +38,8 @@ pub fn create_client( pub fn connect_client( mut client: UniqueViewMut ) { - if !client.0.has_not_made_connection_attempts() { + if client.0.has_not_made_connection_attempts() { + log::info!("Connect called"); client.0.connect().unwrap(); } } From 6b55688dbdf2de525ca76a962afe651d68156cd8 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 22:30:03 +0100 Subject: [PATCH 094/160] change default server port --- Server.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server.toml b/Server.toml index 36d87ae..d290581 100644 --- a/Server.toml +++ b/Server.toml @@ -1,3 +1,3 @@ [server] -address = "0.0.0.0:1234" +address = "0.0.0.0:12345" max_clients = 254 From bda8e7b94cc60ac943de776e3ee08ba20f3aa250 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 22:38:51 +0100 Subject: [PATCH 095/160] disconnect on exit --- kubi-udp/src/client.rs | 6 ++++++ kubi/src/main.rs | 6 ++++-- kubi/src/networking.rs | 19 +++++++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index be9d6e1..50d02de 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -128,6 +128,12 @@ impl Client where S: Encode + Decode, R: Encode + Decode { Ok(()) } + #[inline] + pub fn set_nonblocking(&mut self, is_nonblocking: bool) -> Result<()> { + self.socket.set_nonblocking(is_nonblocking)?; + Ok(()) + } + #[inline] pub fn get_status(&self) -> ClientStatus { self.status diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 4cdfce5..3032daf 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -75,7 +75,7 @@ use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state}; -use networking::{update_networking, is_multiplayer}; +use networking::{update_networking, is_multiplayer, disconnect_on_exit}; use init::initialize_from_args; use gui::{render_gui, init_gui, update_gui}; use loading_screen::update_loading_screen; @@ -104,7 +104,7 @@ fn update() -> Workload { update_window_size, update_cursor_lock_state, process_inputs, - exit_on_esc, + ( update_networking ).into_workload().run_if(is_multiplayer), @@ -124,6 +124,8 @@ fn update() -> Workload { compute_cameras, update_gui, update_state, + exit_on_esc, + disconnect_on_exit, ).into_workload() } fn render() -> Workload { diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 16450b0..7ef0678 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -1,4 +1,5 @@ -use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, WorkloadModificator, EntitiesView, EntitiesViewMut, Component, ViewMut, SystemModificator}; +use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator}; +use glium::glutin::event_loop::ControlFlow; use std::net::SocketAddr; use kubi_udp::client::{Client, ClientConfig, ClientEvent}; use kubi_shared::networking::{ @@ -6,7 +7,7 @@ use kubi_shared::networking::{ state::ClientJoinState }; -use crate::events::EventComponent; +use crate::{events::EventComponent, control_flow::SetControlFlow}; #[derive(Unique, Clone, Copy, PartialEq, Eq)] pub enum GameType { @@ -73,6 +74,20 @@ pub fn update_networking() -> Workload { ).into_workload() } +pub fn disconnect_on_exit( + control_flow: UniqueView, + mut client: UniqueViewMut, +) { + if let Some(ControlFlow::ExitWithCode(_)) = control_flow.0 { + client.0.set_nonblocking(false).expect("Failed to switch socket to blocking mode"); + if let Err(error) = client.0.disconnect() { + log::error!("failed to disconnect: {}", error); + } else { + log::info!("Client disconnected"); + } + } +} + pub fn is_multiplayer( game_type: UniqueView ) -> bool { From 455b4580de7b99216457dcbff50221ff36907fd4 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 22:41:27 +0100 Subject: [PATCH 096/160] Disconnect only in multiplayer --- kubi/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 3032daf..2e8d9dd 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -7,7 +7,7 @@ use shipyard::{ World, Workload, IntoWorkload, UniqueView, UniqueViewMut, - NonSendSync, WorkloadModificator + NonSendSync, WorkloadModificator, SystemModificator }; use glium::{ glutin::{ @@ -125,7 +125,7 @@ fn update() -> Workload { update_gui, update_state, exit_on_esc, - disconnect_on_exit, + disconnect_on_exit.run_if(is_multiplayer), ).into_workload() } fn render() -> Workload { From a5b35ffa7dc5446c12e166196e4f79319957a6d6 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 12 Feb 2023 22:42:39 +0100 Subject: [PATCH 097/160] rename to `connect_client_if_needed` --- kubi/src/networking.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 7ef0678..fb8f53e 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -36,9 +36,11 @@ pub fn create_client( storages.add_unique(ClientJoinState::Disconnected); } -pub fn connect_client( +pub fn connect_client_if_needed( mut client: UniqueViewMut ) { + //NOTE: this used to be a condition function + //but that caused some issues for no reason if client.0.has_not_made_connection_attempts() { log::info!("Connect called"); client.0.connect().unwrap(); @@ -68,7 +70,7 @@ pub fn insert_client_events( pub fn update_networking() -> Workload { ( create_client.run_if_missing_unique::(), - connect_client, + connect_client_if_needed, update_client, insert_client_events, ).into_workload() From 6b9243a5560ee54f38847d869b3231b7825dae9a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 13 Feb 2023 01:53:55 +0100 Subject: [PATCH 098/160] protocol id --- Server.toml | 1 + kubi-server/src/config.rs | 1 + kubi-server/src/server.rs | 7 +++- kubi-shared/src/networking/messages.rs | 6 ++- kubi-udp/src/client.rs | 36 +++++++++++++---- kubi-udp/src/common.rs | 3 ++ kubi-udp/src/packet.rs | 20 +++++++--- kubi-udp/src/server.rs | 55 +++++++++++++++++++------- kubi/src/gui.rs | 8 ++-- kubi/src/init.rs | 2 +- kubi/src/loading_screen.rs | 4 +- kubi/src/world/chunk.rs | 7 +--- 12 files changed, 106 insertions(+), 44 deletions(-) diff --git a/Server.toml b/Server.toml index d290581..14ae320 100644 --- a/Server.toml +++ b/Server.toml @@ -1,3 +1,4 @@ [server] address = "0.0.0.0:12345" max_clients = 254 +timeout_ms = 10000 diff --git a/kubi-server/src/config.rs b/kubi-server/src/config.rs index a16dbf2..4593221 100644 --- a/kubi-server/src/config.rs +++ b/kubi-server/src/config.rs @@ -6,6 +6,7 @@ use std::{fs, net::SocketAddr}; pub struct ConfigTableServer { pub address: SocketAddr, pub max_clients: usize, + pub timeout_ms: u64, } #[derive(Unique, Serialize, Deserialize)] diff --git a/kubi-server/src/server.rs b/kubi-server/src/server.rs index 589b160..e69d710 100644 --- a/kubi-server/src/server.rs +++ b/kubi-server/src/server.rs @@ -1,6 +1,7 @@ use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut}; use kubi_udp::server::{Server, ServerConfig}; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; +use std::time::Duration; use crate::config::ConfigTable; #[derive(Unique)] @@ -14,7 +15,11 @@ pub fn bind_server( let config = storages.borrow::>().unwrap(); let server: Server = Server::bind( config.server.address, - ServerConfig { max_clients: config.server.max_clients } + ServerConfig { + max_clients: config.server.max_clients, + client_timeout: Duration::from_millis(config.server.timeout_ms), + ..Default::default() + } ).unwrap(); storages.add_unique(UdpServer(server)); } diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index 9a84abf..5578781 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -5,7 +5,9 @@ type IVec3Arr = [i32; 3]; type Vec3Arr = [f32; 3]; type QuatArr = [f32; 3]; -#[derive(Encode, Decode)] +pub const PROTOCOL_ID: u16 = 1; + +#[derive(Encode, Decode, Clone)] pub enum ClientToServerMessage { ClientHello { username: String, @@ -21,7 +23,7 @@ pub enum ClientToServerMessage { }, } -#[derive(Encode, Decode)] +#[derive(Encode, Decode, Clone)] pub enum ServerToClientMessage { ServerHello, ServerFuckOff { diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 50d02de..cb411b1 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -6,11 +6,10 @@ use std::{ collections::{VecDeque, vec_deque::Drain as DrainDeque}, io::ErrorKind, }; -use bincode::{Encode, Decode}; use crate::{ BINCODE_CONFIG, - packet::{ClientPacket, IdClientPacket, IdServerPacket, ServerPacket}, - common::ClientId + packet::{ClientPacket, IdClientPacket, IdServerPacket, ServerPacket, Message}, + common::{ClientId, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID} }; #[derive(Default, Clone, Debug)] @@ -22,6 +21,7 @@ pub enum DisconnectReason { KickedByServer(Option), Timeout, ConnectionReset, + InvalidProtocolId, } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -33,25 +33,27 @@ pub enum ClientStatus { #[derive(Clone, Copy, Debug)] pub struct ClientConfig { + pub protocol_id: u16, pub timeout: Duration, pub heartbeat_interval: Duration, } impl Default for ClientConfig { fn default() -> Self { Self { + protocol_id: DEFAULT_USER_PROTOCOL_ID, timeout: Duration::from_secs(5), heartbeat_interval: Duration::from_secs(3), } } } -pub enum ClientEvent where T: Encode + Decode { +pub enum ClientEvent where T: Message { Connected(ClientId), Disconnected(DisconnectReason), MessageReceived(T) } -pub struct Client where S: Encode + Decode, R: Encode + Decode { +pub struct Client where S: Message, R: Message { config: ClientConfig, addr: SocketAddr, socket: UdpSocket, @@ -63,9 +65,15 @@ pub struct Client where S: Encode + Decode, R: Encode + Decode { event_queue: VecDeque>, _s: PhantomData, } -impl Client where S: Encode + Decode, R: Encode + Decode { +impl Client where S: Message, R: Message { #[inline] pub fn new(addr: SocketAddr, config: ClientConfig) -> Result { + if config.protocol_id == 0 { + log::warn!("Warning: using 0 as protocol_id is not recommended"); + } + if config.protocol_id == DEFAULT_USER_PROTOCOL_ID { + log::warn!("Warning: using default protocol_id is not recommended"); + } let bind_addr: SocketAddr = "0.0.0.0:0".parse().unwrap(); let socket = UdpSocket::bind(bind_addr)?; socket.set_nonblocking(true)?; @@ -107,7 +115,7 @@ impl Client where S: Encode + Decode, R: Encode + Decode { #[inline] pub fn connect(&mut self) -> Result<()> { - log::info!("client connect called"); + log::info!("Client connecting.."); if self.status != ClientStatus::Disconnected { bail!("Not Disconnected"); } @@ -115,7 +123,10 @@ impl Client where S: Encode + Decode, R: Encode + Decode { self.last_heartbeat = Instant::now(); self.reset_timeout(); self.socket.connect(self.addr)?; - self.send_raw_packet(ClientPacket::Connect)?; + self.send_raw_packet(ClientPacket::Connect{ + user_protocol: self.config.protocol_id, + inner_protocol: PROTOCOL_ID, + })?; Ok(()) } @@ -216,6 +227,15 @@ impl Client where S: Encode + Decode, R: Encode + Decode { }, ServerPacket::Data(message) => { self.event_queue.push_back(ClientEvent::MessageReceived(message)); + self.timeout = Instant::now(); + }, + ServerPacket::Heartbeat => { + self.timeout = Instant::now(); + }, + ServerPacket::ProtoDisconnect => { + let reason = DisconnectReason::InvalidProtocolId; + self.disconnect_inner(reason, true)?; //this should never fail but we're handling the error anyway + return Ok(()); } } }, diff --git a/kubi-udp/src/common.rs b/kubi-udp/src/common.rs index 76e92b2..84b2822 100644 --- a/kubi-udp/src/common.rs +++ b/kubi-udp/src/common.rs @@ -3,3 +3,6 @@ use std::num::NonZeroU8; pub type ClientId = NonZeroU8; pub type ClientIdRepr = u8; pub const MAX_CLIENTS: usize = u8::MAX as _; + +pub const PROTOCOL_ID: u16 = 1; +pub const DEFAULT_USER_PROTOCOL_ID: u16 = 0xcafe; diff --git a/kubi-udp/src/packet.rs b/kubi-udp/src/packet.rs index 8f13403..b5eff11 100644 --- a/kubi-udp/src/packet.rs +++ b/kubi-udp/src/packet.rs @@ -1,25 +1,33 @@ use bincode::{Encode, Decode}; use crate::common::ClientId; +pub trait Message: Encode + Decode + Clone {} +impl Message for T {} + #[repr(u8)] #[derive(Encode, Decode)] -pub enum ClientPacket where T: Encode + Decode { +pub enum ClientPacket where T: Message { + Connect { + inner_protocol: u16, + user_protocol: u16, + }, //should always stay 0! Data(T), - Connect, Disconnect, Heartbeat, } #[derive(Encode, Decode)] -pub struct IdClientPacket(pub Option, pub ClientPacket); +pub struct IdClientPacket(pub Option, pub ClientPacket); #[repr(u8)] #[derive(Encode, Decode)] -pub enum ServerPacket where T: Encode + Decode { +pub enum ServerPacket where T: Message { + ProtoDisconnect = 0, Data(T), - Connected(ClientId), Disconnected(String), + Connected(ClientId), + Heartbeat, } #[derive(Encode, Decode)] -pub struct IdServerPacket(pub Option, pub ServerPacket); +pub struct IdServerPacket(pub Option, pub ServerPacket); diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index b15a185..18fa508 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -1,18 +1,17 @@ use std::{ net::{UdpSocket, SocketAddr}, - time::Instant, + time::{Instant, Duration}, marker::PhantomData, collections::{VecDeque, vec_deque::Drain as DrainDeque}, io::ErrorKind }; use anyhow::{Result, bail}; -use bincode::{Encode, Decode}; use hashbrown::HashMap; use nohash_hasher::BuildNoHashHasher; use crate::{ BINCODE_CONFIG, - common::{ClientId, ClientIdRepr, MAX_CLIENTS}, - packet::{IdClientPacket, ClientPacket, ServerPacket, IdServerPacket} + common::{ClientId, ClientIdRepr, MAX_CLIENTS, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID}, + packet::{IdClientPacket, ClientPacket, ServerPacket, IdServerPacket, Message} }; //i was feeling a bit sick while writing most of this please excuse me for my terrible code :3 @@ -26,16 +25,20 @@ pub struct ConnectedClient { #[derive(Clone, Copy, Debug)] pub struct ServerConfig { pub max_clients: usize, + pub client_timeout: Duration, + pub protocol_id: u16, } impl Default for ServerConfig { fn default() -> Self { Self { max_clients: MAX_CLIENTS, + client_timeout: Duration::from_secs(5), + protocol_id: DEFAULT_USER_PROTOCOL_ID, } } } -pub enum ServerEvent where T: Encode + Decode { +pub enum ServerEvent where T: Message { Connected(ClientId), Disconnected(ClientId), MessageReceived { @@ -44,16 +47,22 @@ pub enum ServerEvent where T: Encode + Decode { } } -pub struct Server where S: Encode + Decode, R: Encode + Decode { +pub struct Server where S: Message, R: Message { socket: UdpSocket, clients: HashMap>, config: ServerConfig, event_queue: VecDeque>, _s: PhantomData, } -impl Server where S: Encode + Decode, R: Encode + Decode { +impl Server where S: Message, R: Message { pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result { - assert!(config.max_clients <= MAX_CLIENTS); + assert!(config.max_clients <= MAX_CLIENTS, "max_clients value exceeds the maximum allowed amount of clients"); + if config.protocol_id == 0 { + log::warn!("Warning: using 0 as protocol_id is not recommended"); + } + if config.protocol_id == DEFAULT_USER_PROTOCOL_ID { + log::warn!("Warning: using default protocol_id is not recommended"); + } let socket = UdpSocket::bind(addr)?; socket.set_nonblocking(true)?; Ok(Self { @@ -127,6 +136,12 @@ impl Server where S: Encode + Decode, R: Encode + Decode { self.send_packet(IdServerPacket(Some(id), ServerPacket::Data(message)))?; Ok(()) } + pub fn multicast_message(&mut self, _clients: impl IntoIterator, _message: S) { + todo!() + } + pub fn broadcast_message(&mut self, _message: S) -> anyhow::Result<()> { + todo!() + } pub fn update(&mut self) -> Result<()> { //TODO client timeout @@ -141,7 +156,10 @@ impl Server where S: Encode + Decode, R: Encode + Decode { Some(id) => { if !self.clients.contains_key(&id) { bail!("Client with id {id} doesn't exist"); - }; + } + if self.clients.get(&id).unwrap().addr != addr { + bail!("Client addr doesn't match"); + } match packet { ClientPacket::Data(data) => { self.event_queue.push_back(ServerEvent::MessageReceived { @@ -155,21 +173,30 @@ impl Server where S: Encode + Decode, R: Encode + Decode { self.disconnect_client_inner(id, "Disconnected".into())?; }, ClientPacket::Heartbeat => { - self.clients.get_mut(&id).unwrap().timeout = Instant::now() + self.clients.get_mut(&id).unwrap().timeout = Instant::now(); + self.send_packet(IdServerPacket(Some(id), ServerPacket::Heartbeat))?; }, - ClientPacket::Connect => bail!("Client already connected"), + ClientPacket::Connect{..} => bail!("Client already connected"), } }, None => { match packet { - ClientPacket::Connect => { + ClientPacket::Connect { user_protocol, inner_protocol } => { + if (inner_protocol != PROTOCOL_ID) || (user_protocol != self.config.protocol_id ) { + log::error!("Client conenction refused: Invalid protocol id"); + self.send_to_addr(addr, + IdServerPacket(None, ServerPacket::ProtoDisconnect) + )?; + continue; + } + match self.add_client(addr) { Ok(id) => { log::info!("Client with id {id} connected"); self.event_queue.push_back(ServerEvent::Connected(id)); self.send_to_addr(addr, - IdServerPacket(None, ServerPacket::Connected(id) - ))?; + IdServerPacket(None, ServerPacket::Connected(id)) + )?; }, Err(error) => { let reason = error.to_string(); diff --git a/kubi/src/gui.rs b/kubi/src/gui.rs index 73ac0d9..e45af3a 100644 --- a/kubi/src/gui.rs +++ b/kubi/src/gui.rs @@ -1,11 +1,11 @@ -use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, AllStoragesViewMut, View, UniqueView, NonSendSync, UniqueViewMut, IntoIter}; -use glam::{Vec4, Mat3, vec2, Mat4}; -use crate::{color::color_hex, transform::Transform2d, events::WindowResizedEvent, rendering::Renderer}; +use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, View, UniqueViewMut, IntoIter}; +use glam::{Vec4, Mat4}; +use crate::{color::color_hex, events::WindowResizedEvent}; pub mod text_widget; pub mod progressbar; -use progressbar::{render_progressbars, ProgressbarComponent}; +use progressbar::render_progressbars; //TODO compute gui scale on window resize #[derive(Unique, Clone, Copy, Debug, Default)] diff --git a/kubi/src/init.rs b/kubi/src/init.rs index 24536c6..23500e9 100644 --- a/kubi/src/init.rs +++ b/kubi/src/init.rs @@ -1,5 +1,5 @@ use shipyard::{AllStoragesViewMut, UniqueViewMut}; -use std::{env, net::SocketAddr, borrow::BorrowMut}; +use std::{env, net::SocketAddr}; use crate::{ networking::{GameType, ServerAddress}, state::{GameState, NextState} diff --git a/kubi/src/loading_screen.rs b/kubi/src/loading_screen.rs index 02242aa..75873ff 100644 --- a/kubi/src/loading_screen.rs +++ b/kubi/src/loading_screen.rs @@ -47,7 +47,7 @@ fn update_progress_bar_progress ( ) { let bar = (&mut bar).get(eid.0).unwrap(); let loaded = world.chunks.iter().fold(0, |acc, (&_, chunk)| { - acc + chunk.desired_state.matches(chunk.current_state) as usize + acc + chunk.desired_state.matches_current(chunk.current_state) as usize }); let total = world.chunks.len(); let progress = loaded as f32 / total as f32; @@ -62,7 +62,7 @@ fn switch_to_ingame_if_loaded( return } if world.chunks.iter().all(|(_, chunk)| { - chunk.desired_state.matches(chunk.current_state) + chunk.desired_state.matches_current(chunk.current_state) }) { log::info!("Finished loading chunks"); state.0 = Some(GameState::InGame); diff --git a/kubi/src/world/chunk.rs b/kubi/src/world/chunk.rs index cd8f77e..f22801f 100644 --- a/kubi/src/world/chunk.rs +++ b/kubi/src/world/chunk.rs @@ -30,11 +30,6 @@ pub enum CurrentChunkState { RecalculatingMesh, Unloading, } -impl CurrentChunkState { - pub fn matches(self, desired: DesiredChunkState) -> bool { - desired.matches(self) - } -} #[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] pub enum DesiredChunkState { @@ -45,7 +40,7 @@ pub enum DesiredChunkState { ToUnload, } impl DesiredChunkState { - pub fn matches(self, current: CurrentChunkState) -> bool { + pub fn matches_current(self, current: CurrentChunkState) -> bool { (matches!(self, DesiredChunkState::Nothing) && matches!(current, CurrentChunkState::Nothing)) || (matches!(self, DesiredChunkState::Loaded) && matches!(current, CurrentChunkState::Loaded)) || (matches!(self, DesiredChunkState::Rendered) && matches!(current, CurrentChunkState::Rendered)) From b3990e64c9f4a5825ec088f5b0864d7842ee564f Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 13 Feb 2023 01:56:14 +0100 Subject: [PATCH 099/160] change default protocol id --- kubi-udp/src/common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi-udp/src/common.rs b/kubi-udp/src/common.rs index 84b2822..bb74b63 100644 --- a/kubi-udp/src/common.rs +++ b/kubi-udp/src/common.rs @@ -5,4 +5,4 @@ pub type ClientIdRepr = u8; pub const MAX_CLIENTS: usize = u8::MAX as _; pub const PROTOCOL_ID: u16 = 1; -pub const DEFAULT_USER_PROTOCOL_ID: u16 = 0xcafe; +pub const DEFAULT_USER_PROTOCOL_ID: u16 = 0xffff; From cc2175ec3e5a5becfa30a19fa4d98151078a5dbf Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 13 Feb 2023 01:57:30 +0100 Subject: [PATCH 100/160] use `AllStoragesView` instead of `AllStoragesViewMut` --- kubi/src/init.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubi/src/init.rs b/kubi/src/init.rs index 23500e9..c36a747 100644 --- a/kubi/src/init.rs +++ b/kubi/src/init.rs @@ -1,4 +1,4 @@ -use shipyard::{AllStoragesViewMut, UniqueViewMut}; +use shipyard::{AllStoragesView, UniqueViewMut}; use std::{env, net::SocketAddr}; use crate::{ networking::{GameType, ServerAddress}, @@ -6,7 +6,7 @@ use crate::{ }; pub fn initialize_from_args( - mut all_storages: AllStoragesViewMut, + all_storages: AllStoragesView, ) { let args: Vec = env::args().collect(); if args.len() > 1 { From f19683c1b19282b1b1aee22a9b86a2e95c4b38e0 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 13 Feb 2023 02:01:25 +0100 Subject: [PATCH 101/160] remove `pub` from functions --- kubi/src/networking.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index fb8f53e..8c50747 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -1,4 +1,4 @@ -use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator}; +use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator, View, IntoIter}; use glium::glutin::event_loop::ControlFlow; use std::net::SocketAddr; use kubi_udp::client::{Client, ClientConfig, ClientEvent}; @@ -24,7 +24,7 @@ pub struct UdpClient(pub Client); #[derive(Component)] pub struct NetworkEvent(pub ClientEvent); -pub fn create_client( +fn create_client( storages: AllStoragesView ) { log::info!("Creating client"); @@ -36,7 +36,7 @@ pub fn create_client( storages.add_unique(ClientJoinState::Disconnected); } -pub fn connect_client_if_needed( +fn connect_client_if_needed( mut client: UniqueViewMut ) { //NOTE: this used to be a condition function @@ -47,13 +47,13 @@ pub fn connect_client_if_needed( } } -pub fn update_client( +fn update_client( mut client: UniqueViewMut, ) { client.0.update().unwrap(); } -pub fn insert_client_events( +fn insert_client_events( mut client: UniqueViewMut, mut entities: EntitiesViewMut, mut events: ViewMut, From 32963044f3d51cddfbcd791d0d4d500b5b14f51b Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 13 Feb 2023 02:03:09 +0100 Subject: [PATCH 102/160] add log to `disconnect_inner` --- kubi-udp/src/client.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index cb411b1..49cdde8 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -99,6 +99,7 @@ impl Client where S: Message, R: Message { } fn disconnect_inner(&mut self, reason: DisconnectReason, silent: bool) -> Result<()> { + log::info!("client disconnected because {reason:?}"); if !silent { self.send_raw_packet(ClientPacket::Disconnect)?; } From 95c681d0fc74980ac55031b5f5f43bfc83f7d6f1 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 13 Feb 2023 02:30:33 +0100 Subject: [PATCH 103/160] kick inactive clients --- kubi-udp/src/server.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index 18fa508..daf4b9a 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -74,12 +74,17 @@ impl Server where S: Message, R: Message { }) } - fn send_to_addr(&self, addr: SocketAddr, packet: IdServerPacket) -> Result<()> { + + fn send_to_addr_inner(socket: &UdpSocket, addr: SocketAddr, packet: IdServerPacket) -> Result<()> { let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; - self.socket.send_to(&bytes, addr)?; + socket.send_to(&bytes, addr)?; Ok(()) } + fn send_to_addr(&self, addr: SocketAddr, packet: IdServerPacket) -> Result<()> { + Self::send_to_addr_inner(&self.socket, addr, packet) + } + fn send_packet(&self, packet: IdServerPacket) -> Result<()> { let Some(id) = packet.0 else { bail!("send_to_client call without id") @@ -144,7 +149,21 @@ impl Server where S: Message, R: Message { } pub fn update(&mut self) -> Result<()> { - //TODO client timeout + //kick inactive clients + self.clients.retain(|&id, client| { + if client.timeout.elapsed() > self.config.client_timeout { + if let Err(_) = Self::send_to_addr_inner(&self.socket, client.addr, IdServerPacket( + Some(id), ServerPacket::Disconnected("Timed out".into()) + )) { + log::warn!("Client {id} timed out and we failed to send the kick packet. This shouldn't reaally matter") + } else { + log::info!("Client {id} timed out"); + } + return false + } + true + }); + let mut buf = [0; u16::MAX as usize]; loop { match self.socket.recv_from(&mut buf) { From bccd3a8cfdd2e0108bd081d343d2cd1afc518129 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 13 Feb 2023 02:57:09 +0100 Subject: [PATCH 104/160] implement broadcase and multicast functions --- kubi-udp/src/server.rs | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index daf4b9a..ad1074c 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -5,7 +5,7 @@ use std::{ collections::{VecDeque, vec_deque::Drain as DrainDeque}, io::ErrorKind }; -use anyhow::{Result, bail}; +use anyhow::{Result, Error, bail}; use hashbrown::HashMap; use nohash_hasher::BuildNoHashHasher; use crate::{ @@ -137,17 +137,30 @@ impl Server where S: Message, R: Message { Ok(()) } - pub fn send_message(&mut self, id: ClientId, message: S) -> anyhow::Result<()> { + pub fn send_message(&mut self, id: ClientId, message: S) -> Result<()> { self.send_packet(IdServerPacket(Some(id), ServerPacket::Data(message)))?; Ok(()) } - pub fn multicast_message(&mut self, _clients: impl IntoIterator, _message: S) { - todo!() + pub fn multicast_message(&mut self, clients: impl IntoIterator, message: S) -> Vec { + //TODO use actual udp multicast + let mut errors = Vec::with_capacity(0); + for client in clients { + if let Err(error) = self.send_message(client, message.clone()) { + log::error!("Message broadcast failed for id {client}"); + errors.push(error); + } + } + errors } - pub fn broadcast_message(&mut self, _message: S) -> anyhow::Result<()> { - todo!() + pub fn broadcast_message(&mut self, message: S) -> Vec { + let ids = self.clients.keys().copied().collect::>(); + self.multicast_message(ids, message) } - + pub fn broadcast_message_except(&mut self, except: ClientId, message: S) -> Vec { + let ids = self.clients.keys().copied().filter(|&k| k != except).collect::>(); + self.multicast_message(ids, message) + } + pub fn update(&mut self) -> Result<()> { //kick inactive clients self.clients.retain(|&id, client| { From 41a1a5d00bde74da89cad3abb24b0d1db1277610 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 13 Feb 2023 03:01:29 +0100 Subject: [PATCH 105/160] set `publish` to false --- kubi-server/Cargo.toml | 1 + kubi-shared/Cargo.toml | 1 + kubi-udp/Cargo.toml | 1 + kubi/Cargo.toml | 1 + 4 files changed, 4 insertions(+) diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index d2856d9..f9e056e 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -2,6 +2,7 @@ name = "kubi-server" version = "0.1.0" edition = "2021" +publish = false [dependencies] kubi-shared = { path = "../kubi-shared" } diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 7fb813f..73e4cd5 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -2,6 +2,7 @@ name = "kubi-shared" version = "0.1.0" edition = "2021" +publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/kubi-udp/Cargo.toml b/kubi-udp/Cargo.toml index f08a674..605363e 100644 --- a/kubi-udp/Cargo.toml +++ b/kubi-udp/Cargo.toml @@ -2,6 +2,7 @@ name = "kubi-udp" version = "0.1.0" edition = "2021" +publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 90d9250..4d586d8 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -2,6 +2,7 @@ name = "kubi" version = "0.1.0" edition = "2021" +publish = false [dependencies] kubi-shared = { path = "../kubi-shared" } From 1b1f6c6426e66090e269364169fc957fb25f7289 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 13 Feb 2023 04:12:02 +0100 Subject: [PATCH 106/160] wip connect --- kubi-shared/src/networking/state.rs | 4 +-- kubi/src/connecting_screen.rs | 12 ++++++++ kubi/src/main.rs | 14 ++++++--- kubi/src/state.rs | 6 ++++ kubi/src/world/tasks.rs | 44 +++++++++++++++++++++++++++-- 5 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 kubi/src/connecting_screen.rs diff --git a/kubi-shared/src/networking/state.rs b/kubi-shared/src/networking/state.rs index dbed8e1..dd9a8b5 100644 --- a/kubi-shared/src/networking/state.rs +++ b/kubi-shared/src/networking/state.rs @@ -1,13 +1,13 @@ use shipyard::{Unique, Component}; // disconnected => connect => join => load => ingame -#[derive(Unique, Component)] +#[derive(Unique, Component, PartialEq, Eq, Clone, Copy)] pub enum ClientJoinState { /// Not connected yet Disconnected, /// Client has connected to the game, but hasn't authenticated yet Connected, - /// Client has joined the game, but haven't loaded the world yet + /// Client has joined the game, but hasn't loaded the world yet Joined, /// Client is currently ingame InGame, diff --git a/kubi/src/connecting_screen.rs b/kubi/src/connecting_screen.rs new file mode 100644 index 0000000..047311b --- /dev/null +++ b/kubi/src/connecting_screen.rs @@ -0,0 +1,12 @@ +use kubi_shared::networking::state::ClientJoinState; +use shipyard::{UniqueViewMut, UniqueView}; +use crate::state::{NextState, GameState}; + +pub fn switch_to_loading_if_connected( + mut next_state: UniqueViewMut, + client_state: UniqueView, +) { + if *client_state == ClientJoinState::Joined { + next_state.0 = Some(GameState::LoadingWorld); + } +} diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 2e8d9dd..c02f929 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -39,12 +39,14 @@ pub(crate) mod networking; pub(crate) mod init; pub(crate) mod color; pub(crate) mod loading_screen; +pub(crate) mod connecting_screen; use world::{ init_game_world, loading::update_loaded_world_around_player, raycast::update_raycasts, - queue::apply_queued_blocks + queue::apply_queued_blocks, + tasks::inject_network_responses_into_manager_queue }; use player::spawn_player; use prefabs::load_prefabs; @@ -74,11 +76,12 @@ use block_placement::block_placement_system; use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; -use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state}; +use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state, is_connecting}; use networking::{update_networking, is_multiplayer, disconnect_on_exit}; use init::initialize_from_args; use gui::{render_gui, init_gui, update_gui}; use loading_screen::update_loading_screen; +use connecting_screen::switch_to_loading_if_connected; fn startup() -> Workload { ( @@ -104,10 +107,13 @@ fn update() -> Workload { update_window_size, update_cursor_lock_state, process_inputs, - ( - update_networking + update_networking, + inject_network_responses_into_manager_queue, ).into_workload().run_if(is_multiplayer), + ( + switch_to_loading_if_connected + ).into_workload().run_if(is_connecting), ( update_loading_screen, ).into_workload().run_if(is_loading), diff --git a/kubi/src/state.rs b/kubi/src/state.rs index 3301964..7ab1b4c 100644 --- a/kubi/src/state.rs +++ b/kubi/src/state.rs @@ -35,6 +35,12 @@ pub fn is_changing_state( state.0.is_some() } +pub fn is_connecting( + state: UniqueView +) -> bool { + *state == GameState::Connecting +} + pub fn is_ingame( state: UniqueView ) -> bool { diff --git a/kubi/src/world/tasks.rs b/kubi/src/world/tasks.rs index 2c73c16..82da68a 100644 --- a/kubi/src/world/tasks.rs +++ b/kubi/src/world/tasks.rs @@ -1,13 +1,15 @@ use flume::{Sender, Receiver}; use glam::IVec3; -use shipyard::Unique; +use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; +use shipyard::{Unique, UniqueView, View, IntoIter}; use rayon::{ThreadPool, ThreadPoolBuilder}; use super::{ chunk::BlockData, mesh::{generate_mesh, data::MeshGenData}, worldgen::generate_world, }; -use crate::rendering::world::ChunkVertex; +use crate::{rendering::world::ChunkVertex, networking::{UdpClient, NetworkEvent}}; +use kubi_udp::client::ClientEvent; pub enum ChunkTask { LoadChunk { @@ -43,6 +45,11 @@ impl ChunkTaskManager { pool: ThreadPoolBuilder::new().num_threads(4).build().unwrap() } } + pub fn add_sussy_response(&self, response: ChunkTaskResponse) { + // this WILL get stuck if the channel is bounded + // don't make the channel bounded ever + self.channel.0.send(response).unwrap() + } pub fn spawn_task(&self, task: ChunkTask) { let sender = self.channel.0.clone(); self.pool.spawn(move || { @@ -62,3 +69,36 @@ impl ChunkTaskManager { self.channel.1.try_recv().ok() } } + +pub fn spawn_task_or_get_from_network_if_possible(client: Option<&mut UdpClient>, manager: &mut ChunkTaskManager, task: ChunkTask) { + match &task { + ChunkTask::LoadChunk { seed, position } => { + match client { + Some(client) => { + client.0.send_message(ClientToServerMessage::ChunkRequest { chunk: position.to_array() }).unwrap(); + }, + None => { + manager.spawn_task(task) + } + } + }, + _ => { + manager.spawn_task(task) + } + } +} + +//TODO get rid of this, this is awfulll +pub fn inject_network_responses_into_manager_queue( + manager: UniqueView, + events: View +) { + for event in events.iter() { + if let ClientEvent::MessageReceived(ServerToClientMessage::ChunkResponse { chunk, data }) = &event.0 { + let position = IVec3::from_array(*chunk); + manager.add_sussy_response(ChunkTaskResponse::LoadedChunk { + position, chunk_data: data.clone() + }); + } + } +} From c284d5f7eda7a3c66808083e4d3dcc495e1866ea Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 04:27:27 +0100 Subject: [PATCH 107/160] basic client auth --- kubi-server/Cargo.toml | 1 + kubi-server/src/auth.rs | 41 ++++++++++++++++++++++++++ kubi-server/src/chunk.rs | 13 ++++++++ kubi-server/src/config.rs | 1 + kubi-server/src/main.rs | 9 +++++- kubi-server/src/server.rs | 18 +++++++++-- kubi-server/src/util.rs | 3 ++ kubi-shared/src/networking/messages.rs | 9 +++++- 8 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 kubi-server/src/auth.rs create mode 100644 kubi-server/src/chunk.rs create mode 100644 kubi-server/src/util.rs diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index f9e056e..13c0063 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -15,6 +15,7 @@ toml = "0.7" glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } hashbrown = "0.13" nohash-hasher = "0.2.0" +anyhow = "1.0" [features] default = [] diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs new file mode 100644 index 0000000..ad5098a --- /dev/null +++ b/kubi-server/src/auth.rs @@ -0,0 +1,41 @@ +use shipyard::{UniqueView, UniqueViewMut}; +use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage, InitData}; +use kubi_udp::server::ServerEvent; +use crate::{server::{ServerEvents, UdpServer}, config::ConfigTable, util::log_error}; + +pub fn authenticate_players( + mut server: UniqueViewMut, + events: UniqueView, + config: UniqueView +) { + for event in &events.0 { + if let ServerEvent::MessageReceived { + from, + message: ClientToServerMessage::ClientHello { + username, + password + } + } = event { + // Handle password auth + if let Some(server_password) = &config.server.password { + if let Some(user_password) = &password { + if server_password != user_password { + server.0.send_message(*from, ServerToClientMessage::ServerFuckOff { + reason: "Passwords don't match".into() + }).map_err(log_error).ok(); + continue + } + } else { + server.0.send_message(*from, ServerToClientMessage::ServerFuckOff { + reason: "This server is password-protected".into() + }).map_err(log_error).ok(); + continue + } + } + //Approve the user + server.0.send_message(*from, ServerToClientMessage::ServerHello { + init: InitData {} + }).map_err(log_error).ok(); + } + } +} diff --git a/kubi-server/src/chunk.rs b/kubi-server/src/chunk.rs new file mode 100644 index 0000000..26210cd --- /dev/null +++ b/kubi-server/src/chunk.rs @@ -0,0 +1,13 @@ +pub struct Chunk { + //TODO +} + +pub struct ChunkManager { + //TODO +} + +pub fn server_chunk_response( + +) { + +} diff --git a/kubi-server/src/config.rs b/kubi-server/src/config.rs index 4593221..2ae114f 100644 --- a/kubi-server/src/config.rs +++ b/kubi-server/src/config.rs @@ -7,6 +7,7 @@ pub struct ConfigTableServer { pub address: SocketAddr, pub max_clients: usize, pub timeout_ms: u64, + pub password: Option, } #[derive(Unique, Serialize, Deserialize)] diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index bb6f60e..926c6b5 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -1,12 +1,17 @@ + use shipyard::{World, Workload, IntoWorkload}; use std::{thread, time::Duration}; +pub(crate) mod util; pub(crate) mod config; pub(crate) mod server; pub(crate) mod client; +pub(crate) mod chunk; +pub(crate) mod auth; use config::read_config; -use server::{bind_server, update_server}; +use server::{bind_server, update_server, update_server_events}; +use auth::authenticate_players; fn initialize() -> Workload { ( @@ -18,6 +23,8 @@ fn initialize() -> Workload { fn update() -> Workload { ( update_server, + update_server_events, + authenticate_players, ).into_workload() } diff --git a/kubi-server/src/server.rs b/kubi-server/src/server.rs index e69d710..c9bde00 100644 --- a/kubi-server/src/server.rs +++ b/kubi-server/src/server.rs @@ -1,12 +1,15 @@ use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut}; -use kubi_udp::server::{Server, ServerConfig}; +use kubi_udp::server::{Server, ServerConfig, ServerEvent}; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; use std::time::Duration; use crate::config::ConfigTable; #[derive(Unique)] #[repr(transparent)] -pub struct UdpServer(Server); +pub struct UdpServer(pub Server); + +#[derive(Unique, Default)] +pub struct ServerEvents(pub Vec>); pub fn bind_server( storages: AllStoragesView, @@ -22,6 +25,7 @@ pub fn bind_server( } ).unwrap(); storages.add_unique(UdpServer(server)); + storages.add_unique(ServerEvents::default()); } pub fn update_server( @@ -31,3 +35,13 @@ pub fn update_server( log::error!("Server error: {error:?}") } } + +pub fn update_server_events( + mut server: UniqueViewMut, + mut events: UniqueViewMut, +) { + //drop current events + events.0.clear(); + //fetch new ones + events.0.extend(server.0.process_events().rev()); +} diff --git a/kubi-server/src/util.rs b/kubi-server/src/util.rs new file mode 100644 index 0000000..2438d9e --- /dev/null +++ b/kubi-server/src/util.rs @@ -0,0 +1,3 @@ +pub fn log_error(error: anyhow::Error) { + log::error!("{}", error); +} diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index 5578781..95b7b16 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -23,9 +23,16 @@ pub enum ClientToServerMessage { }, } +#[derive(Encode, Decode, Clone)] +pub struct InitData { + +} + #[derive(Encode, Decode, Clone)] pub enum ServerToClientMessage { - ServerHello, + ServerHello { + init: InitData + }, ServerFuckOff { reason: String, }, From 4440b07bbe9cbd54d92066dd1bdebd6be9267dc8 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 04:31:17 +0100 Subject: [PATCH 108/160] add todo --- kubi-server/src/auth.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs index ad5098a..eb2b634 100644 --- a/kubi-server/src/auth.rs +++ b/kubi-server/src/auth.rs @@ -32,6 +32,10 @@ pub fn authenticate_players( continue } } + + //Spawn the user + // TODO + //Approve the user server.0.send_message(*from, ServerToClientMessage::ServerHello { init: InitData {} From 740fa04910d5efee6fb53bea478078cead670c94 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 04:52:11 +0100 Subject: [PATCH 109/160] wip --- kubi-server/src/auth.rs | 6 ++++-- kubi-shared/src/networking/messages.rs | 13 ++++++++++++- kubi-udp/src/lib.rs | 1 + 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs index eb2b634..5a376a0 100644 --- a/kubi-server/src/auth.rs +++ b/kubi-server/src/auth.rs @@ -35,10 +35,12 @@ pub fn authenticate_players( //Spawn the user // TODO - + //Approve the user server.0.send_message(*from, ServerToClientMessage::ServerHello { - init: InitData {} + init: InitData { + users: todo!() + } }).map_err(log_error).ok(); } } diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index 95b7b16..0b553c6 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -1,3 +1,5 @@ +use std::num::NonZeroUsize; + use bincode::{Encode, Decode}; use crate::chunk::BlockData; @@ -23,9 +25,18 @@ pub enum ClientToServerMessage { }, } +#[derive(Encode, Decode, Clone)] +pub struct UserInitData { + pub client_id: NonZeroUsize, //maybe use the proper type instead + pub username: String, + pub position: Vec3Arr, + pub velocity: Vec3Arr, + pub direction: QuatArr, +} + #[derive(Encode, Decode, Clone)] pub struct InitData { - + pub users: Vec } #[derive(Encode, Decode, Clone)] diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs index ae5678c..82588e3 100644 --- a/kubi-udp/src/lib.rs +++ b/kubi-udp/src/lib.rs @@ -4,6 +4,7 @@ pub(crate) mod packet; pub(crate) mod common; pub use common::ClientId; pub use common::ClientIdRepr; +pub use common::MAX_CLIENTS; //pub(crate) trait Serializable: bincode::Encode + bincode::Decode {} pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() From dada84e097ecafe2d0cf0150f5881a8e988435e5 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 19:09:27 +0100 Subject: [PATCH 110/160] ad entity to shared --- kubi-shared/src/entity.rs | 18 ++++++++++++++++++ kubi-shared/src/lib.rs | 1 + 2 files changed, 19 insertions(+) create mode 100644 kubi-shared/src/entity.rs diff --git a/kubi-shared/src/entity.rs b/kubi-shared/src/entity.rs new file mode 100644 index 0000000..bf2f183 --- /dev/null +++ b/kubi-shared/src/entity.rs @@ -0,0 +1,18 @@ +use shipyard::Component; + +#[derive(Component)] +pub struct Entity; + +#[derive(Component)] +pub struct Health { + pub current: u8, + pub max: u8, +} +impl Health { + fn new(health: u8) -> Self { + Self { + current: health, + max: health + } + } +} diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs index 13cb165..3817e6f 100644 --- a/kubi-shared/src/lib.rs +++ b/kubi-shared/src/lib.rs @@ -3,3 +3,4 @@ pub mod networking; pub mod worldgen; pub mod chunk; pub mod transform; +pub mod entity; From 7b6d50abe5da9a990632e2f960ca97f66bdc1110 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 19:31:20 +0100 Subject: [PATCH 111/160] Migrate to shipyard master --- kubi-server/Cargo.toml | 2 +- kubi-shared/Cargo.toml | 2 +- kubi/Cargo.toml | 2 +- kubi/src/camera/frustum.rs | 8 ++++---- kubi/src/camera/matrices.rs | 10 +++++----- kubi/src/events/player_actions.rs | 4 ++-- kubi/src/fly_controller.rs | 6 +++--- kubi/src/gui/progressbar.rs | 7 ++++--- kubi/src/loading_screen.rs | 6 +++--- kubi/src/rendering/world.rs | 4 ++-- kubi/src/world/loading.rs | 4 ++-- kubi/src/world/raycast.rs | 6 +++--- 12 files changed, 31 insertions(+), 30 deletions(-) diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 13c0063..db71968 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -9,7 +9,7 @@ kubi-shared = { path = "../kubi-shared" } kubi-udp = { path = "../kubi-udp" } kubi-logging = { path = "../kubi-logging" } log = "*" -shipyard = "0.6" +shipyard = { git = "https://github.com/leudz/shipyard", rev = "9fd2aaa32bccee29bd7fc99ccaabec950fe13ed0" } serde = "1.0" toml = "0.7" glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 73e4cd5..3bb4711 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] glam = { version = "0.22", features = ["debug-glam-assert", "fast-math", "serde"] } -shipyard = "0.6" +shipyard = { git = "https://github.com/leudz/shipyard", rev = "9fd2aaa32bccee29bd7fc99ccaabec950fe13ed0" } strum = { version = "0.24", features = ["derive"] } bincode = "2.0.0-rc" anyhow = "1.0" diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 4d586d8..6fe7557 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -15,7 +15,7 @@ image = { version = "0.24", default_features = false, features = ["png"] } strum = { version = "0.24", features = ["derive"] } hashbrown = "0.13" rayon = "1.6" -shipyard = { version = "0.6", features = ["thread_local"] } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "9fd2aaa32bccee29bd7fc99ccaabec950fe13ed0", features = ["thread_local"] } nohash-hasher = "0.2.0" anyhow = "1.0" flume = "0.10" diff --git a/kubi/src/camera/frustum.rs b/kubi/src/camera/frustum.rs index 9042dd4..7fc00f3 100644 --- a/kubi/src/camera/frustum.rs +++ b/kubi/src/camera/frustum.rs @@ -8,7 +8,7 @@ // three layers of stolen code, yay! use glam::{Vec3A, Vec4, Mat3A, vec3a, Vec3, vec4}; -use shipyard::{ViewMut, IntoIter, View}; +use shipyard::{ViewMut, IntoIter, View, track}; use crate::transform::Transform; use super::Camera; @@ -122,9 +122,9 @@ fn intersection(planes: &[Vec4; pub fn update_frustum( mut cameras: ViewMut, - transforms: View + transforms: View ) { - for (camera, _) in (&mut cameras, transforms.inserted_or_modified()).iter() { - camera.frustum = Frustum::compute(camera); + for (mut camera, _) in (&mut cameras, transforms.inserted_or_modified()).iter() { + camera.frustum = Frustum::compute(&camera); } } diff --git a/kubi/src/camera/matrices.rs b/kubi/src/camera/matrices.rs index 7537700..5f2c003 100644 --- a/kubi/src/camera/matrices.rs +++ b/kubi/src/camera/matrices.rs @@ -1,5 +1,5 @@ use glam::{Vec3, Mat4}; -use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload}; +use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track}; use crate::{transform::Transform, events::WindowResizedEvent}; use super::Camera; @@ -7,11 +7,11 @@ use super::Camera; fn update_view_matrix( mut vm_camera: ViewMut, - v_transform: View + v_transform: View ) { - for (camera, transform) in (&mut vm_camera, v_transform.inserted_or_modified()).iter() { + for (mut camera, transform) in (&mut vm_camera, v_transform.inserted_or_modified()).iter() { let (_, rotation, translation) = transform.0.to_scale_rotation_translation(); - let direction = (rotation * Vec3::NEG_Z).normalize(); + let direction = (rotation.normalize() * Vec3::NEG_Z).normalize(); camera.view_matrix = Mat4::look_to_rh(translation, direction, camera.up); } } @@ -24,7 +24,7 @@ fn update_perspective_matrix( let Some(&size) = resize.iter().next() else { return }; - for camera in (&mut vm_camera).iter() { + for mut camera in (&mut vm_camera).iter() { camera.perspective_matrix = Mat4::perspective_rh_gl( camera.fov, size.0.x as f32 / size.0.y as f32, diff --git a/kubi/src/events/player_actions.rs b/kubi/src/events/player_actions.rs index 09b8a0c..7c086d2 100644 --- a/kubi/src/events/player_actions.rs +++ b/kubi/src/events/player_actions.rs @@ -1,4 +1,4 @@ -use shipyard::{Component, View, ViewMut, EntitiesViewMut, IntoIter}; +use shipyard::{Component, View, ViewMut, EntitiesViewMut, IntoIter, track}; use glam::{IVec3, Quat, Vec3}; use crate::{ @@ -21,7 +21,7 @@ pub enum PlayerActionEvent { } pub fn generate_move_events( - transforms: View, + transforms: View, player: View, mut entities: EntitiesViewMut, mut events: ViewMut, diff --git a/kubi/src/fly_controller.rs b/kubi/src/fly_controller.rs index 81b5ea8..57276cb 100644 --- a/kubi/src/fly_controller.rs +++ b/kubi/src/fly_controller.rs @@ -1,5 +1,5 @@ use glam::{Vec3, Mat4, Quat, EulerRot, Vec2}; -use shipyard::{Component, View, ViewMut, IntoIter, UniqueView, Workload, IntoWorkload}; +use shipyard::{Component, View, ViewMut, IntoIter, UniqueView, Workload, IntoWorkload, track}; use std::f32::consts::PI; use crate::{transform::Transform, input::Inputs, settings::GameSettings, delta_time::DeltaTime}; @@ -17,7 +17,7 @@ const MAX_PITCH: f32 = PI/2. - 0.05; fn update_look( controllers: View, - mut transforms: ViewMut, + mut transforms: ViewMut, inputs: UniqueView, settings: UniqueView, dt: UniqueView, @@ -37,7 +37,7 @@ fn update_look( fn update_movement( controllers: View, - mut transforms: ViewMut, + mut transforms: ViewMut, inputs: UniqueView, dt: UniqueView, ) { diff --git a/kubi/src/gui/progressbar.rs b/kubi/src/gui/progressbar.rs index 9a945c7..0fe9b26 100644 --- a/kubi/src/gui/progressbar.rs +++ b/kubi/src/gui/progressbar.rs @@ -1,11 +1,12 @@ -use shipyard::{UniqueView, UniqueViewMut, NonSendSync, View, Component, IntoIter, IntoWithId, Get}; +use shipyard::{UniqueView, UniqueViewMut, NonSendSync, View, Component, IntoIter, IntoWithId, Get, track}; use glium::{Surface, uniform, DrawParameters}; use crate::{ prefabs::ProgressbarShaderPrefab, rendering::{ RenderTarget, primitives::rect::RectPrimitive - }, transform::Transform2d, + }, + transform::Transform2d, }; use super::{GuiComponent, PrimaryColor, SecondaryColor, GuiView}; @@ -20,7 +21,7 @@ pub fn render_progressbars( program: NonSendSync>, view: UniqueView, components: View, - transforms: View, + transforms: View, progressbars: View, primary: View, secondary: View, diff --git a/kubi/src/loading_screen.rs b/kubi/src/loading_screen.rs index 75873ff..cb01e21 100644 --- a/kubi/src/loading_screen.rs +++ b/kubi/src/loading_screen.rs @@ -1,4 +1,4 @@ -use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload, EntityId, Unique, AllStoragesViewMut, ViewMut, Get, SystemModificator}; +use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload, EntityId, Unique, AllStoragesViewMut, ViewMut, Get, SystemModificator, track}; use glam::{Mat3, vec2}; use crate::{ world::ChunkStorage, @@ -34,7 +34,7 @@ fn spawn_loading_screen( fn resize_progress_bar( size: UniqueView, bar: UniqueView, - mut transforms: ViewMut + mut transforms: ViewMut ) { let mut trans = (&mut transforms).get(bar.0).unwrap(); trans.0.x_axis.x = size.0.x as f32; @@ -45,7 +45,7 @@ fn update_progress_bar_progress ( mut bar: ViewMut, eid: UniqueView, ) { - let bar = (&mut bar).get(eid.0).unwrap(); + let mut bar = (&mut bar).get(eid.0).unwrap(); let loaded = world.chunks.iter().fold(0, |acc, (&_, chunk)| { acc + chunk.desired_state.matches_current(chunk.current_state) as usize }); diff --git a/kubi/src/rendering/world.rs b/kubi/src/rendering/world.rs index 9029381..81d94c7 100644 --- a/kubi/src/rendering/world.rs +++ b/kubi/src/rendering/world.rs @@ -1,5 +1,5 @@ use glam::{Vec3, Mat4, Quat, ivec3}; -use shipyard::{NonSendSync, UniqueView, UniqueViewMut, View, IntoIter}; +use shipyard::{NonSendSync, UniqueView, UniqueViewMut, View, IntoIter, track}; use glium::{ implement_vertex, uniform, Surface, DrawParameters, @@ -114,7 +114,7 @@ pub fn draw_world( pub fn draw_current_chunk_border( mut target: NonSendSync>, player: View, - transforms: View, + transforms: View, buffers: NonSendSync>, program: NonSendSync>, camera: View, diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index 3b6fb83..18c0172 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -1,6 +1,6 @@ use glam::{IVec3, ivec3}; use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType}; -use shipyard::{View, UniqueView, UniqueViewMut, IntoIter, Workload, IntoWorkload, NonSendSync}; +use shipyard::{View, UniqueView, UniqueViewMut, IntoIter, Workload, IntoWorkload, NonSendSync, track}; use crate::{ player::MainPlayer, transform::Transform, @@ -29,7 +29,7 @@ pub fn update_loaded_world_around_player() -> Workload { pub fn update_chunks_if_player_moved( v_settings: UniqueView, v_local_player: View, - v_transform: View, + v_transform: View, mut vm_world: UniqueViewMut, ) { //Check if the player actually moved diff --git a/kubi/src/world/raycast.rs b/kubi/src/world/raycast.rs index 1485abd..d34aafe 100644 --- a/kubi/src/world/raycast.rs +++ b/kubi/src/world/raycast.rs @@ -1,5 +1,5 @@ use glam::{Vec3, IVec3}; -use shipyard::{View, Component, ViewMut, IntoIter, UniqueView}; +use shipyard::{View, Component, ViewMut, IntoIter, UniqueView, track}; use crate::{transform::Transform, world::block::BlockDescriptorSource}; use super::{ChunkStorage, block::Block}; @@ -48,7 +48,7 @@ impl ChunkStorage { pub struct LookingAtBlock(pub Option); pub fn update_raycasts( - transform: View, + transform: View, mut raycast: ViewMut, world: UniqueView, ) { @@ -56,7 +56,7 @@ pub fn update_raycasts( if !(world.is_inserted_or_modified() || (transform.inserted_or_modified(), &raycast).iter().next().is_some()) { return } - for (transform, report) in (&transform, &mut raycast).iter() { + for (transform, mut report) in (&transform, &mut raycast).iter() { let (_, rotation, position) = transform.0.to_scale_rotation_translation(); let direction = (rotation * Vec3::NEG_Z).normalize(); *report = LookingAtBlock(world.raycast(position, direction, Some(30.))); From a8142468a25f6549231306a729b7ca09cac48b95 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 19:35:47 +0100 Subject: [PATCH 112/160] remove `track(...)` --- kubi-shared/src/transform.rs | 2 -- kubi/src/cursor_lock.rs | 1 - kubi/src/state.rs | 2 -- kubi/src/world.rs | 1 - 4 files changed, 6 deletions(-) diff --git a/kubi-shared/src/transform.rs b/kubi-shared/src/transform.rs index 6d38bfe..c918deb 100644 --- a/kubi-shared/src/transform.rs +++ b/kubi-shared/src/transform.rs @@ -2,9 +2,7 @@ use shipyard::Component; use glam::{Mat4, Mat3}; #[derive(Component, Clone, Copy, Debug, Default)] -#[track(All)] pub struct Transform(pub Mat4); #[derive(Component, Clone, Copy, Debug, Default)] -#[track(All)] pub struct Transform2d(pub Mat3); diff --git a/kubi/src/cursor_lock.rs b/kubi/src/cursor_lock.rs index 2c3303b..6512017 100644 --- a/kubi/src/cursor_lock.rs +++ b/kubi/src/cursor_lock.rs @@ -3,7 +3,6 @@ use crate::rendering::Renderer; use glium::glutin::window::CursorGrabMode; #[derive(Unique)] -#[track(All)] pub struct CursorLock(pub bool); pub fn update_cursor_lock_state( diff --git a/kubi/src/state.rs b/kubi/src/state.rs index 7ab1b4c..a01d228 100644 --- a/kubi/src/state.rs +++ b/kubi/src/state.rs @@ -2,7 +2,6 @@ use shipyard::{Unique, UniqueView, UniqueViewMut, AllStoragesView}; use std::mem::take; #[derive(Unique, PartialEq, Eq, Default, Clone, Copy)] -#[track(All)] pub enum GameState { #[default] Initial, @@ -12,7 +11,6 @@ pub enum GameState { } #[derive(Unique, PartialEq, Eq, Default, Clone, Copy)] -#[track(All)] pub struct NextState(pub Option); pub fn init_state( diff --git a/kubi/src/world.rs b/kubi/src/world.rs index 4d8684d..5f94085 100644 --- a/kubi/src/world.rs +++ b/kubi/src/world.rs @@ -24,7 +24,6 @@ use queue::BlockUpdateQueue; // because this is not send-sync #[derive(Default, Unique)] -#[track(Modification)] pub struct ChunkStorage { pub chunks: HashMap } From 8a4339506ee9b7c322dbb5fc2c65a627eaeda958 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 19:54:52 +0100 Subject: [PATCH 113/160] update `shipyard` to the lastest commit --- kubi-server/Cargo.toml | 2 +- kubi-shared/Cargo.toml | 2 +- kubi/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index db71968..064d000 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -9,7 +9,7 @@ kubi-shared = { path = "../kubi-shared" } kubi-udp = { path = "../kubi-udp" } kubi-logging = { path = "../kubi-logging" } log = "*" -shipyard = { git = "https://github.com/leudz/shipyard", rev = "9fd2aaa32bccee29bd7fc99ccaabec950fe13ed0" } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "e30dece" } serde = "1.0" toml = "0.7" glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 3bb4711..b615b4f 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] glam = { version = "0.22", features = ["debug-glam-assert", "fast-math", "serde"] } -shipyard = { git = "https://github.com/leudz/shipyard", rev = "9fd2aaa32bccee29bd7fc99ccaabec950fe13ed0" } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "e30dece" } strum = { version = "0.24", features = ["derive"] } bincode = "2.0.0-rc" anyhow = "1.0" diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 6fe7557..56f5841 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -15,7 +15,7 @@ image = { version = "0.24", default_features = false, features = ["png"] } strum = { version = "0.24", features = ["derive"] } hashbrown = "0.13" rayon = "1.6" -shipyard = { git = "https://github.com/leudz/shipyard", rev = "9fd2aaa32bccee29bd7fc99ccaabec950fe13ed0", features = ["thread_local"] } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "e30dece", features = ["thread_local"] } nohash-hasher = "0.2.0" anyhow = "1.0" flume = "0.10" From 3209bf45d63da9bf13429d6596327858ab47c8e0 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 20:01:11 +0100 Subject: [PATCH 114/160] oops `Cargo.lock` was in `.gitignore` --- .gitignore | 4 - Cargo.lock | 2231 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2231 insertions(+), 4 deletions(-) create mode 100644 Cargo.lock diff --git a/.gitignore b/.gitignore index 07db1ba..1b52c1b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,10 +3,6 @@ debug/ target/ -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..060d7b7 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2231 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bincode" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb50c5a2ef4b9b1e7ae73e3a73b52ea24b20312d629f9c4df28260b7ad2c3c4" +dependencies = [ + "bincode_derive", + "serde", +] + +[[package]] +name = "bincode_derive" +version = "2.0.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a45a23389446d2dd25dc8e73a7a3b3c43522b630cac068927f0649d43d719d2" +dependencies = [ + "virtue", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "bracket-noise" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0b7443d0990c69db7a83f376f0101d684c20a911698e5f932bffbda2c8b08dd" +dependencies = [ + "bracket-random", +] + +[[package]] +name = "bracket-random" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "437be61484077b1ddb57002ce3c96b7d03cbf500b5d15157ee7e67e22332c39b" +dependencies = [ + "getrandom", + "js-sys", + "lazy_static", + "rand", + "rand_xorshift", + "regex", + "wasm-bindgen", +] + +[[package]] +name = "bumpalo" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" + +[[package]] +name = "bytemuck" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "calloop" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a59225be45a478d772ce015d9743e49e92798ece9e34eda9a6aa2a6a7f40192" +dependencies = [ + "log", + "nix 0.25.1", + "slotmap", + "thiserror", + "vec_map", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cgl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" +dependencies = [ + "libc", +] + +[[package]] +name = "cmake" +version = "0.1.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c" +dependencies = [ + "cc", +] + +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types 0.3.2", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", + "objc", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "core-text" +version = "19.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" +dependencies = [ + "core-foundation", + "core-graphics", + "foreign-types 0.3.2", + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset 0.7.1", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossfont" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21fd3add36ea31aba1520aa5288714dd63be506106753226d0eb387a93bc9c45" +dependencies = [ + "cocoa", + "core-foundation", + "core-foundation-sys", + "core-graphics", + "core-text", + "dwrote", + "foreign-types 0.5.0", + "freetype-rs", + "libc", + "log", + "objc", + "once_cell", + "pkg-config", + "servo-fontconfig", + "winapi", +] + +[[package]] +name = "cty" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" + +[[package]] +name = "darling" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dwrote" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" +dependencies = [ + "lazy_static", + "libc", + "serde", + "serde_derive", + "winapi", + "wio", +] + +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + +[[package]] +name = "env_logger" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "expat-sys" +version = "2.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" +dependencies = [ + "cmake", + "pkg-config", +] + +[[package]] +name = "flate2" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8469d0d40519bc608ec6863f1cc88f3f1deee15913f2f3b3e573d81ed38cccc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "freetype-rs" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb" +dependencies = [ + "bitflags", + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" +dependencies = [ + "cmake", + "libc", + "pkg-config", +] + +[[package]] +name = "futures-core" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" + +[[package]] +name = "futures-sink" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" + +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gilrs" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d0342acdc7b591d171212e17c9350ca02383b86d5f9af33c6e3598e03a6c57e" +dependencies = [ + "fnv", + "gilrs-core", + "log", + "uuid", + "vec_map", +] + +[[package]] +name = "gilrs-core" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6789d356476c3280a4e15365d23f62b4b4f1bcdac81fdd552f65807bce4666dd" +dependencies = [ + "core-foundation", + "io-kit-sys", + "js-sys", + "libc", + "libudev-sys", + "log", + "nix 0.25.1", + "rusty-xinput", + "uuid", + "vec_map", + "wasm-bindgen", + "web-sys", + "winapi", +] + +[[package]] +name = "gimli" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" + +[[package]] +name = "gl_generator" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" +dependencies = [ + "khronos_api", + "log", + "xml-rs", +] + +[[package]] +name = "glam" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774" +dependencies = [ + "serde", +] + +[[package]] +name = "glium" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2766728ecb86014b91d3d687614b32d65aacbbdc887f424a7b03cba3ab593bf" +dependencies = [ + "backtrace", + "fnv", + "gl_generator", + "glutin", + "lazy_static", + "memoffset 0.6.5", + "smallvec", + "takeable-option", +] + +[[package]] +name = "glutin" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444c9ad294fdcaf20ccf6726b78f380b5450275540c9b68ab62f49726ad1c713" +dependencies = [ + "cgl", + "cocoa", + "core-foundation", + "glutin_egl_sys", + "glutin_gles2_sys", + "glutin_glx_sys", + "glutin_wgl_sys", + "libloading", + "log", + "objc", + "once_cell", + "osmesa-sys", + "parking_lot", + "raw-window-handle 0.5.0", + "wayland-client", + "wayland-egl", + "winapi", + "winit", +] + +[[package]] +name = "glutin_egl_sys" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68900f84b471f31ea1d1355567eb865a2cf446294f06cef8d653ed7bcf5f013d" +dependencies = [ + "gl_generator", + "winapi", +] + +[[package]] +name = "glutin_gles2_sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094e708b730a7c8a1954f4f8a31880af00eb8a1c5b5bf85d28a0a3c6d69103" +dependencies = [ + "gl_generator", + "objc", +] + +[[package]] +name = "glutin_glx_sys" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93d0575865098580c5b3a423188cd959419912ea60b1e48e8b3b526f6d02468" +dependencies = [ + "gl_generator", + "x11-dl", +] + +[[package]] +name = "glutin_wgl_sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da5951a1569dbab865c6f2a863efafff193a93caf05538d193e9e3816d21696" +dependencies = [ + "gl_generator", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.3", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "image" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b7ea949b537b0fd0af141fff8c77690f2ce96f4f41f042ccb6c69c6c965945" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-rational", + "num-traits", + "png", +] + +[[package]] +name = "indexmap" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "io-kit-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7789f7f3c9686f96164f5109d69152de759e76e284f736bd57661c6df5091919" +dependencies = [ + "core-foundation-sys", + "mach", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +dependencies = [ + "libc", + "windows-sys 0.45.0", +] + +[[package]] +name = "is-terminal" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "js-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445dde2150c55e483f3d8416706b97ec8e8237c307e5b7b4b8dd15e6af2a0730" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "khronos_api" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" + +[[package]] +name = "kubi" +version = "0.1.0" +dependencies = [ + "anyhow", + "flume", + "gilrs", + "glam", + "glium", + "hashbrown 0.13.2", + "image", + "kubi-logging", + "kubi-shared", + "kubi-udp", + "log", + "nohash-hasher", + "rayon", + "shipyard", + "strum", + "winapi", +] + +[[package]] +name = "kubi-logging" +version = "0.1.0" +dependencies = [ + "env_logger", + "log", +] + +[[package]] +name = "kubi-server" +version = "0.1.0" +dependencies = [ + "anyhow", + "glam", + "hashbrown 0.13.2", + "kubi-logging", + "kubi-shared", + "kubi-udp", + "log", + "nohash-hasher", + "serde", + "shipyard", + "toml", +] + +[[package]] +name = "kubi-shared" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "bracket-noise", + "glam", + "shipyard", + "strum", +] + +[[package]] +name = "kubi-udp" +version = "0.1.0" +dependencies = [ + "anyhow", + "bincode", + "hashbrown 0.13.2", + "kubi-logging", + "log", + "nohash-hasher", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.139" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libudev-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "linux-raw-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memmap2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.45.0", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys", + "num_enum", + "raw-window-handle 0.5.0", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-glue" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0434fabdd2c15e0aab768ca31d5b7b333717f03cf02037d5a0a3ff3c278ed67f" +dependencies = [ + "libc", + "log", + "ndk", + "ndk-context", + "ndk-macro", + "ndk-sys", + "once_cell", + "parking_lot", +] + +[[package]] +name = "ndk-macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c" +dependencies = [ + "darling", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom8" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" +dependencies = [ + "memchr", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +dependencies = [ + "hermit-abi 0.2.6", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d829733185c1ca374f17e52b762f24f535ec625d2cc1f070e34c8a9068f341b" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2be1598bf1c313dcdd12092e3f1920f463462525a21b7b4e11b4168353d0123e" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + +[[package]] +name = "object" +version = "0.30.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" + +[[package]] +name = "osmesa-sys" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b" +dependencies = [ + "shared_library", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys 0.45.0", +] + +[[package]] +name = "percent-encoding" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "png" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638" +dependencies = [ + "bitflags", + "crc32fast", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34" +dependencies = [ + "once_cell", + "toml_edit 0.18.1", +] + +[[package]] +name = "proc-macro2" +version = "1.0.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "raw-window-handle" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" +dependencies = [ + "cty", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a" +dependencies = [ + "cty", +] + +[[package]] +name = "rayon" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustix" +version = "0.36.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.45.0", +] + +[[package]] +name = "rustversion" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" + +[[package]] +name = "rusty-xinput" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2aa654bc32eb9ca14cce1a084abc9dfe43949a4547c35269a094c39272db3bb" +dependencies = [ + "lazy_static", + "log", + "winapi", +] + +[[package]] +name = "safe_arch" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ff3d6d9696af502cc3110dacce942840fb06ff4514cad92236ecc455f2ce05" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sctk-adwaita" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61270629cc6b4d77ec1907db1033d5c2e1a404c412743621981a871dc9c12339" +dependencies = [ + "crossfont", + "log", + "smithay-client-toolkit", + "tiny-skia", +] + +[[package]] +name = "serde" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_spanned" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +dependencies = [ + "serde", +] + +[[package]] +name = "servo-fontconfig" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" +dependencies = [ + "libc", + "servo-fontconfig-sys", +] + +[[package]] +name = "servo-fontconfig-sys" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" +dependencies = [ + "expat-sys", + "freetype-sys", + "pkg-config", +] + +[[package]] +name = "shared_library" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "shipyard" +version = "0.6.0" +source = "git+https://github.com/leudz/shipyard?rev=e30dece#e30dece960c9bd296c659f66215559cb5ccf4351" +dependencies = [ + "hashbrown 0.12.3", + "lock_api", + "rayon", + "shipyard_proc", +] + +[[package]] +name = "shipyard_proc" +version = "0.3.0" +source = "git+https://github.com/leudz/shipyard?rev=e30dece#e30dece960c9bd296c659f66215559cb5ccf4351" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + +[[package]] +name = "smithay-client-toolkit" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454" +dependencies = [ + "bitflags", + "calloop", + "dlib", + "lazy_static", + "log", + "memmap2", + "nix 0.24.3", + "pkg-config", + "wayland-client", + "wayland-cursor", + "wayland-protocols", +] + +[[package]] +name = "spin" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dccf47db1b41fa1573ed27ccf5e08e3ca771cb994f776668c5ebda893b248fc" +dependencies = [ + "lock_api", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "takeable-option" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36ae8932fcfea38b7d3883ae2ab357b0d57a02caaa18ebb4f5ece08beaec4aa0" + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tiny-skia" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "png", + "safe_arch", + "tiny-skia-path", +] + +[[package]] +name = "tiny-skia-path" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c114d32f0c2ee43d585367cb013dfaba967ab9f62b90d9af0d696e955e70fa6c" +dependencies = [ + "arrayref", + "bytemuck", +] + +[[package]] +name = "toml" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime 0.6.1", + "toml_edit 0.19.3", +] + +[[package]] +name = "toml_datetime" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" +dependencies = [ + "indexmap", + "nom8", + "toml_datetime 0.5.1", +] + +[[package]] +name = "toml_edit" +version = "0.19.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6a7712b49e1775fb9a7b998de6635b299237f48b404dde71704f2e0e7f37e5" +dependencies = [ + "indexmap", + "nom8", + "serde", + "serde_spanned", + "toml_datetime 0.6.1", +] + +[[package]] +name = "unicode-ident" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" + +[[package]] +name = "uuid" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1674845326ee10d37ca60470760d4288a6f80f304007d92e5c53bab78c9cfd79" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "virtue" +version = "0.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b60dcd6a64dd45abf9bd426970c9843726da7fc08f44cd6fcebf68c21220a63" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31f8dcbc21f30d9b8f2ea926ecb58f6b91192c17e9d33594b3df58b2007ca53b" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95ce90fd5bcc06af55a641a86428ee4229e44e07033963a2290a8e241607ccb9" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c21f77c0bedc37fd5dc21f897894a5ca01e7bb159884559461862ae90c0b4c5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.84" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" + +[[package]] +name = "wayland-client" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" +dependencies = [ + "bitflags", + "downcast-rs", + "libc", + "nix 0.24.3", + "scoped-tls", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +dependencies = [ + "nix 0.24.3", + "once_cell", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-cursor" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" +dependencies = [ + "nix 0.24.3", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-egl" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402de949f81a012926d821a2d659f930694257e76dd92b6e0042ceb27be4107d" +dependencies = [ + "wayland-client", + "wayland-sys", +] + +[[package]] +name = "wayland-protocols" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" +dependencies = [ + "bitflags", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" +dependencies = [ + "dlib", + "lazy_static", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc 0.42.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" + +[[package]] +name = "winit" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c" +dependencies = [ + "bitflags", + "cocoa", + "core-foundation", + "core-graphics", + "dispatch", + "instant", + "libc", + "log", + "mio", + "ndk", + "ndk-glue", + "objc", + "once_cell", + "parking_lot", + "percent-encoding", + "raw-window-handle 0.4.3", + "raw-window-handle 0.5.0", + "sctk-adwaita", + "smithay-client-toolkit", + "wasm-bindgen", + "wayland-client", + "wayland-protocols", + "web-sys", + "windows-sys 0.36.1", + "x11-dl", +] + +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "xcursor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" +dependencies = [ + "nom", +] + +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" From e1cf0a1ed014991a6b501fdc93e805f28802ccb3 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 23:00:08 +0100 Subject: [PATCH 115/160] wip better world generation --- kubi-shared/src/worldgen.rs | 136 ++++++++++++++++++++++++++++-------- kubi/src/settings.rs | 2 +- kubi/src/world/raycast.rs | 2 +- 3 files changed, 107 insertions(+), 33 deletions(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 7e84845..9136b45 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -5,45 +5,119 @@ use crate::{ blocks::Block }; +fn local_height(height: i32, chunk_position: IVec3) -> usize { + let offset = chunk_position * CHUNK_SIZE as i32; + (height - offset.y).clamp(0, CHUNK_SIZE as i32) as usize +} +fn local_y_position(height: i32, chunk_position: IVec3) -> Option { + let offset = chunk_position * CHUNK_SIZE as i32; + let position = height - offset.y; + (0..CHUNK_SIZE as i32).contains(&position).then_some(position as usize) +} + pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { let offset = chunk_position * CHUNK_SIZE as i32; - - let mut cave_noise = FastNoise::seeded(seed); - cave_noise.set_fractal_type(FractalType::FBM); - cave_noise.set_frequency(0.1); - - let mut dirt_noise = FastNoise::seeded(seed.rotate_left(1)); - dirt_noise.set_fractal_type(FractalType::FBM); - dirt_noise.set_frequency(0.1); - let mut blocks = Box::new([[[Block::Air; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]); + + let mut height_noise = FastNoise::seeded(seed); + height_noise.set_fractal_type(FractalType::FBM); + height_noise.set_fractal_octaves(4); + height_noise.set_frequency(0.003); - if chunk_position.y >= 0 { - if chunk_position.y == 0 { - for x in 0..CHUNK_SIZE { - for z in 0..CHUNK_SIZE { - blocks[x][0][z] = Block::Dirt; - blocks[x][1][z] = Block::Grass; - } + let mut elevation_noise = FastNoise::seeded(seed); + elevation_noise.set_fractal_type(FractalType::FBM); + elevation_noise.set_fractal_octaves(1); + elevation_noise.set_frequency(0.001); + + // let mut cave_noise = FastNoise::seeded(seed.rotate_left(1)); + // cave_noise.set_fractal_type(FractalType::FBM); + // cave_noise.set_fractal_octaves(2); + // cave_noise.set_frequency(0.001); + + //Generate height map + let mut within_heightmap = false; + for x in 0..CHUNK_SIZE { + for z in 0..CHUNK_SIZE { + let (noise_x, noise_y) = ((offset.x + x as i32) as f32, (offset.z + z as i32) as f32); + //sample noises + let raw_heightmap_value = height_noise.get_noise(noise_x, noise_y); + let raw_elevation_value = elevation_noise.get_noise(noise_x, noise_y); + //compute height + let height = { + let local_elevation = raw_elevation_value.powi(4).sqrt(); + (raw_heightmap_value.clamp(-1., 1.) * local_elevation * 100.) as i32 + }; + //place dirt + for y in 0..local_height(height, chunk_position) { + blocks[x][y][z] = Block::Dirt; + within_heightmap = true; } - } - } else { - for x in 0..CHUNK_SIZE { - for y in 0..CHUNK_SIZE { - for z in 0..CHUNK_SIZE { - let position = ivec3(x as i32, y as i32, z as i32) + offset; - let v_cave_noise = cave_noise.get_noise3d(position.x as f32, position.y as f32, position.z as f32) * (-position.y as f32 - 10.0).clamp(0., 1.); - let v_dirt_noise = dirt_noise.get_noise3d(position.x as f32, position.y as f32, position.z as f32) * (-position.y as f32).clamp(0., 1.); - if v_cave_noise > 0.5 { - blocks[x][y][z] = Block::Stone; - } else if v_dirt_noise > 0.5 { - blocks[x][y][z] = Block::Dirt; - } - } + //place stone + for y in 0..local_height(height - 5 - (raw_heightmap_value * 5.) as i32, chunk_position) { + blocks[x][y][z] = Block::Stone; + within_heightmap = true; + } + //place grass + if let Some(y) = local_y_position(height, chunk_position) { + blocks[x][y][z] = Block::Grass; } } } - + //Carve out mountains + if within_heightmap { + // for z in 0..CHUNK_SIZE { + // for y in 0..CHUNK_SIZE { + // for x in 0..CHUNK_SIZE { + // if blocks[x][y][z] == Block::Air { continue } + // let position = ivec3(x as i32, y as i32, z as i32) + offset; + // let raw_cavemap_value = cave_noise.get_noise3d(position.x as f32, position.y as f32, position.z as f32); + // let is_cave = (-0.3..=-0.3).contains(&raw_cavemap_value); + // if is_cave { + // blocks[x][y][z] = Block::Air; + // } + // } + // } + // } + } + blocks + + // let mut cave_noise = FastNoise::seeded(seed); + // cave_noise.set_fractal_type(FractalType::FBM); + // cave_noise.set_frequency(0.1); + + // let mut dirt_noise = FastNoise::seeded(seed.rotate_left(1)); + // dirt_noise.set_fractal_type(FractalType::FBM); + // dirt_noise.set_frequency(0.1); + + // + + // if chunk_position.y >= 0 { + // if chunk_position.y == 0 { + // for x in 0..CHUNK_SIZE { + // for z in 0..CHUNK_SIZE { + // blocks[x][0][z] = Block::Dirt; + // blocks[x][1][z] = Block::Grass; + // } + // } + // } + // } else { + // for x in 0..CHUNK_SIZE { + // for y in 0..CHUNK_SIZE { + // for z in 0..CHUNK_SIZE { + // let position = ivec3(x as i32, y as i32, z as i32) + offset; + // let v_cave_noise = cave_noise.get_noise3d(position.x as f32, position.y as f32, position.z as f32) * (-position.y as f32 - 10.0).clamp(0., 1.); + // let v_dirt_noise = dirt_noise.get_noise3d(position.x as f32, position.y as f32, position.z as f32) * (-position.y as f32).clamp(0., 1.); + // if v_cave_noise > 0.5 { + // blocks[x][y][z] = Block::Stone; + // } else if v_dirt_noise > 0.5 { + // blocks[x][y][z] = Block::Dirt; + // } + // } + // } + // } + // } + // blocks + } diff --git a/kubi/src/settings.rs b/kubi/src/settings.rs index 97cdde9..02dff02 100644 --- a/kubi/src/settings.rs +++ b/kubi/src/settings.rs @@ -10,7 +10,7 @@ pub struct GameSettings { impl Default for GameSettings { fn default() -> Self { Self { - render_distance: 5, + render_distance: 6, mouse_sensitivity: 1., debug_draw_current_chunk_border: cfg!(debug_assertions), } diff --git a/kubi/src/world/raycast.rs b/kubi/src/world/raycast.rs index d34aafe..90c98a4 100644 --- a/kubi/src/world/raycast.rs +++ b/kubi/src/world/raycast.rs @@ -58,7 +58,7 @@ pub fn update_raycasts( } for (transform, mut report) in (&transform, &mut raycast).iter() { let (_, rotation, position) = transform.0.to_scale_rotation_translation(); - let direction = (rotation * Vec3::NEG_Z).normalize(); + let direction = (rotation.normalize() * Vec3::NEG_Z).normalize(); *report = LookingAtBlock(world.raycast(position, direction, Some(30.))); } } From 3b8eddcad1958fe4d21d65b84171a4fa34414421 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 23:39:14 +0100 Subject: [PATCH 116/160] world gen experimentation --- kubi-shared/src/worldgen.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 9136b45..1d2cad5 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -5,10 +5,22 @@ use crate::{ blocks::Block }; +fn mountain_ramp(mut x: f32) -> f32 { + x = x * 2.0; + if x < 0.4 { + 0.5 * x + } else if x < 0.55 { + 4. * (x - 0.4) + 0.2 + } else { + 0.4444 * (x - 0.55) + 0.8 + } +} + fn local_height(height: i32, chunk_position: IVec3) -> usize { let offset = chunk_position * CHUNK_SIZE as i32; (height - offset.y).clamp(0, CHUNK_SIZE as i32) as usize } + fn local_y_position(height: i32, chunk_position: IVec3) -> Option { let offset = chunk_position * CHUNK_SIZE as i32; let position = height - offset.y; @@ -45,7 +57,9 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { //compute height let height = { let local_elevation = raw_elevation_value.powi(4).sqrt(); - (raw_heightmap_value.clamp(-1., 1.) * local_elevation * 100.) as i32 + let mut height = (mountain_ramp(raw_heightmap_value) * local_elevation * 100.) as i32; + if height < 0 { height /= 2 } + height }; //place dirt for y in 0..local_height(height, chunk_position) { From 51ed3762cc18458fb703523da0231b18cbd609ca Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 23:43:05 +0100 Subject: [PATCH 117/160] disable selbox effect --- kubi/shaders/selection_box.frag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi/shaders/selection_box.frag b/kubi/shaders/selection_box.frag index d18a665..5311d6f 100644 --- a/kubi/shaders/selection_box.frag +++ b/kubi/shaders/selection_box.frag @@ -7,5 +7,5 @@ uniform vec4 u_color; void main() { color = u_color; - color -= vec4(0, 0, 0, 0.1 * sin(gl_FragCoord.x) * cos(gl_FragCoord.y)); + // color -= vec4(0, 0, 0, 0.1 * sin(gl_FragCoord.x) * cos(gl_FragCoord.y)); } From 0de70ed1b77ad175eb2335b940a7d4dba018af58 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 14 Feb 2023 23:48:47 +0100 Subject: [PATCH 118/160] reduce placement dst --- kubi/src/block_placement.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi/src/block_placement.rs b/kubi/src/block_placement.rs index a0f3991..f3d7cd1 100644 --- a/kubi/src/block_placement.rs +++ b/kubi/src/block_placement.rs @@ -23,7 +23,7 @@ pub fn block_placement_system( let Some(ray) = (&main_player, &raycast).iter().next().unwrap().1/**/.0 else { return }; //get coord and block type let (place_position, place_block) = if action_place { - let position = (ray.position - ray.direction * 0.5).floor().as_ivec3(); + let position = (ray.position - ray.direction * 0.251).floor().as_ivec3(); (position, Block::Cobblestone) } else { (ray.block_position, Block::Air) From c865835e8deb49c74025f76e1e8d9f209ab07d5b Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 15 Feb 2023 22:07:47 +0100 Subject: [PATCH 119/160] move block to shared --- {kubi/src/world => kubi-shared/src}/block.rs | 44 ++++++++++++++++++-- kubi-shared/src/blocks.rs | 13 ------ kubi-shared/src/chunk.rs | 2 +- kubi-shared/src/lib.rs | 2 +- kubi-shared/src/worldgen.rs | 2 +- kubi/src/block_placement.rs | 3 +- kubi/src/events/player_actions.rs | 3 +- kubi/src/prefabs.rs | 20 +-------- kubi/src/rendering/world.rs | 1 - kubi/src/world.rs | 4 +- kubi/src/world/mesh.rs | 3 +- kubi/src/world/queue.rs | 2 +- kubi/src/world/raycast.rs | 5 ++- 13 files changed, 55 insertions(+), 49 deletions(-) rename {kubi/src/world => kubi-shared/src}/block.rs (82%) delete mode 100644 kubi-shared/src/blocks.rs diff --git a/kubi/src/world/block.rs b/kubi-shared/src/block.rs similarity index 82% rename from kubi/src/world/block.rs rename to kubi-shared/src/block.rs index 66a0905..e4e5324 100644 --- a/kubi/src/world/block.rs +++ b/kubi-shared/src/block.rs @@ -1,5 +1,35 @@ -use crate::prefabs::BlockTexture; -pub use kubi_shared::blocks::Block; +use bincode::{Encode, Decode}; +use strum::EnumIter; + +#[derive(Clone, Copy, Debug, EnumIter)] +#[repr(u8)] +pub enum BlockTexture { + Stone, + Dirt, + GrassTop, + GrassSide, + Sand, + Bedrock, + Wood, + WoodTop, + Leaf, + Torch, + TallGrass, + Snow, + GrassSideSnow, + Cobblestone, +} + +#[derive(Encode, Decode, Clone, Copy, Debug, PartialEq, Eq, EnumIter)] +#[repr(u8)] +pub enum Block { + Air, + Stone, + Dirt, + Grass, + Sand, + Cobblestone, +} pub trait BlockDescriptorSource { fn descriptor(self) -> BlockDescriptor; @@ -92,6 +122,13 @@ impl CubeTexture { } } +#[derive(Clone, Copy, Debug)] +struct CrossTexture { + pub a: BlockTexture, + pub b: BlockTexture, + +} + #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum CollisionType { None, @@ -101,5 +138,6 @@ pub enum CollisionType { #[derive(Clone, Copy, Debug)] pub enum RenderType { None, - SolidBlock(CubeTexture) + SolidBlock(CubeTexture), + CrossShape, } diff --git a/kubi-shared/src/blocks.rs b/kubi-shared/src/blocks.rs deleted file mode 100644 index 0f94b33..0000000 --- a/kubi-shared/src/blocks.rs +++ /dev/null @@ -1,13 +0,0 @@ -use bincode::{Encode, Decode}; -use strum::EnumIter; - -#[derive(Encode, Decode, Clone, Copy, Debug, PartialEq, Eq, EnumIter)] -#[repr(u8)] -pub enum Block { - Air, - Stone, - Dirt, - Grass, - Sand, - Cobblestone, -} diff --git a/kubi-shared/src/chunk.rs b/kubi-shared/src/chunk.rs index de1b357..3456db5 100644 --- a/kubi-shared/src/chunk.rs +++ b/kubi-shared/src/chunk.rs @@ -1,4 +1,4 @@ -use crate::blocks::Block; +use crate::block::Block; pub const CHUNK_SIZE: usize = 32; pub type BlockData = Box<[[[Block; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>; diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs index 3817e6f..2f1da39 100644 --- a/kubi-shared/src/lib.rs +++ b/kubi-shared/src/lib.rs @@ -1,4 +1,4 @@ -pub mod blocks; +pub mod block; pub mod networking; pub mod worldgen; pub mod chunk; diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 1d2cad5..ca2df3e 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -2,7 +2,7 @@ use glam::{IVec3, ivec3}; use bracket_noise::prelude::*; use crate::{ chunk::{BlockData, CHUNK_SIZE}, - blocks::Block + block::Block }; fn mountain_ramp(mut x: f32) -> f32 { diff --git a/kubi/src/block_placement.rs b/kubi/src/block_placement.rs index f3d7cd1..0a08390 100644 --- a/kubi/src/block_placement.rs +++ b/kubi/src/block_placement.rs @@ -1,7 +1,8 @@ use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut}; +use kubi_shared::block::Block; use crate::{ player::MainPlayer, - world::{raycast::LookingAtBlock, block::Block, queue::{BlockUpdateQueue, BlockUpdateEvent}}, + world::{raycast::LookingAtBlock, queue::{BlockUpdateQueue, BlockUpdateEvent}}, input::{Inputs, PrevInputs}, events::{EventComponent, player_actions::PlayerActionEvent}, }; diff --git a/kubi/src/events/player_actions.rs b/kubi/src/events/player_actions.rs index 7c086d2..7f87606 100644 --- a/kubi/src/events/player_actions.rs +++ b/kubi/src/events/player_actions.rs @@ -1,8 +1,7 @@ use shipyard::{Component, View, ViewMut, EntitiesViewMut, IntoIter, track}; use glam::{IVec3, Quat, Vec3}; - +use kubi_shared::block::Block; use crate::{ - world::block::Block, player::MainPlayer, transform::Transform }; diff --git a/kubi/src/prefabs.rs b/kubi/src/prefabs.rs index 6d1aa76..1fc81b5 100644 --- a/kubi/src/prefabs.rs +++ b/kubi/src/prefabs.rs @@ -1,6 +1,6 @@ use shipyard::{NonSendSync, UniqueView, Unique, AllStoragesView}; use glium::{texture::{SrgbTexture2dArray, MipmapsOption}, Program}; -use strum::EnumIter; +use kubi_shared::block::{Block, BlockTexture}; use crate::rendering::Renderer; mod texture; @@ -13,24 +13,6 @@ pub trait AssetPaths { fn file_name(self) -> &'static str; } -#[derive(Clone, Copy, Debug, EnumIter)] -#[repr(u8)] -pub enum BlockTexture { - Stone, - Dirt, - GrassTop, - GrassSide, - Sand, - Bedrock, - Wood, - WoodTop, - Leaf, - Torch, - TallGrass, - Snow, - GrassSideSnow, - Cobblestone, -} impl AssetPaths for BlockTexture { fn file_name(self) -> &'static str { match self { diff --git a/kubi/src/rendering/world.rs b/kubi/src/rendering/world.rs index 81d94c7..1ff8235 100644 --- a/kubi/src/rendering/world.rs +++ b/kubi/src/rendering/world.rs @@ -110,7 +110,6 @@ pub fn draw_world( } } -//this doesn't use culling! pub fn draw_current_chunk_border( mut target: NonSendSync>, player: View, diff --git a/kubi/src/world.rs b/kubi/src/world.rs index 5f94085..03d91c2 100644 --- a/kubi/src/world.rs +++ b/kubi/src/world.rs @@ -4,10 +4,9 @@ use glam::IVec3; use hashbrown::HashMap; use anyhow::{Result, Context}; -pub use kubi_shared::worldgen; +pub use kubi_shared::{worldgen, block::Block}; pub mod chunk; -pub mod block; pub mod tasks; pub mod loading; pub mod mesh; @@ -15,7 +14,6 @@ pub mod neighbors; pub mod raycast; pub mod queue; -use block::Block; use chunk::{Chunk, ChunkMesh, CHUNK_SIZE}; use tasks::ChunkTaskManager; use queue::BlockUpdateQueue; diff --git a/kubi/src/world/mesh.rs b/kubi/src/world/mesh.rs index 608fc60..b8f738e 100644 --- a/kubi/src/world/mesh.rs +++ b/kubi/src/world/mesh.rs @@ -1,7 +1,8 @@ use strum::{EnumIter, IntoEnumIterator}; use glam::{Vec3A, vec3a, IVec3, ivec3}; use std::mem::discriminant; -use super::{chunk::CHUNK_SIZE, block::{Block, RenderType, BlockDescriptorSource}}; +use kubi_shared::block::{Block, RenderType, BlockDescriptorSource}; +use super::{chunk::CHUNK_SIZE, }; use crate::rendering::world::ChunkVertex; pub mod data; diff --git a/kubi/src/world/queue.rs b/kubi/src/world/queue.rs index bfcaa63..718228c 100644 --- a/kubi/src/world/queue.rs +++ b/kubi/src/world/queue.rs @@ -1,5 +1,5 @@ use glam::{IVec3, ivec3}; -use kubi_shared::{blocks::Block, chunk::CHUNK_SIZE}; +use kubi_shared::{block::Block, chunk::CHUNK_SIZE}; use shipyard::{UniqueViewMut, Unique}; use super::ChunkStorage; diff --git a/kubi/src/world/raycast.rs b/kubi/src/world/raycast.rs index 90c98a4..a71802c 100644 --- a/kubi/src/world/raycast.rs +++ b/kubi/src/world/raycast.rs @@ -1,7 +1,8 @@ use glam::{Vec3, IVec3}; use shipyard::{View, Component, ViewMut, IntoIter, UniqueView, track}; -use crate::{transform::Transform, world::block::BlockDescriptorSource}; -use super::{ChunkStorage, block::Block}; +use kubi_shared::block::{Block, BlockDescriptorSource}; +use crate::transform::Transform; +use super::ChunkStorage; const RAYCAST_STEP: f32 = 0.25; From f5a4e2a532a8669f94a89a8e7e1f031056fd3569 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 15 Feb 2023 22:08:48 +0100 Subject: [PATCH 120/160] inline descriptor --- kubi-shared/src/block.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index e4e5324..6851554 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -35,6 +35,7 @@ pub trait BlockDescriptorSource { fn descriptor(self) -> BlockDescriptor; } impl BlockDescriptorSource for Block { + #[inline] fn descriptor(self) -> BlockDescriptor { match self { Self::Air => BlockDescriptor { From 00b3a90fd460a130d68db1994cbdbfd829a4c32f Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 15 Feb 2023 22:11:15 +0100 Subject: [PATCH 121/160] remove `BlockDescriptorSource` trait --- kubi-shared/src/block.rs | 19 ++++++++++--------- kubi/src/world/mesh.rs | 2 +- kubi/src/world/raycast.rs | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index 6851554..11bad0b 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -31,12 +31,9 @@ pub enum Block { Cobblestone, } -pub trait BlockDescriptorSource { - fn descriptor(self) -> BlockDescriptor; -} -impl BlockDescriptorSource for Block { +impl Block { #[inline] - fn descriptor(self) -> BlockDescriptor { + pub const fn descriptor(self) -> BlockDescriptor { match self { Self::Air => BlockDescriptor { name: "air", @@ -124,9 +121,13 @@ impl CubeTexture { } #[derive(Clone, Copy, Debug)] -struct CrossTexture { - pub a: BlockTexture, - pub b: BlockTexture, +pub struct CrossTexture { + pub a_front: BlockTexture, + pub b_front: BlockTexture, + pub a_back: BlockTexture, + pub b_back: BlockTexture, +} +impl CrossTexture { } @@ -140,5 +141,5 @@ pub enum CollisionType { pub enum RenderType { None, SolidBlock(CubeTexture), - CrossShape, + CrossShape(CrossTexture), } diff --git a/kubi/src/world/mesh.rs b/kubi/src/world/mesh.rs index b8f738e..8b53a58 100644 --- a/kubi/src/world/mesh.rs +++ b/kubi/src/world/mesh.rs @@ -1,7 +1,7 @@ use strum::{EnumIter, IntoEnumIterator}; use glam::{Vec3A, vec3a, IVec3, ivec3}; use std::mem::discriminant; -use kubi_shared::block::{Block, RenderType, BlockDescriptorSource}; +use kubi_shared::block::{Block, RenderType}; use super::{chunk::CHUNK_SIZE, }; use crate::rendering::world::ChunkVertex; diff --git a/kubi/src/world/raycast.rs b/kubi/src/world/raycast.rs index a71802c..c545595 100644 --- a/kubi/src/world/raycast.rs +++ b/kubi/src/world/raycast.rs @@ -1,6 +1,6 @@ use glam::{Vec3, IVec3}; use shipyard::{View, Component, ViewMut, IntoIter, UniqueView, track}; -use kubi_shared::block::{Block, BlockDescriptorSource}; +use kubi_shared::block::Block; use crate::transform::Transform; use super::ChunkStorage; From 2c374c6e233ce110dc82ac0f60e330e2a69dd01c Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 15 Feb 2023 23:32:06 +0100 Subject: [PATCH 122/160] minor refactor --- kubi-shared/src/block.rs | 21 +++++- kubi/src/rendering/world.rs | 1 - kubi/src/world/mesh.rs | 115 +++++++-------------------------- kubi/src/world/mesh/builder.rs | 89 +++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 95 deletions(-) create mode 100644 kubi/src/world/mesh/builder.rs diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index 11bad0b..e42c367 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -29,6 +29,7 @@ pub enum Block { Grass, Sand, Cobblestone, + TallGrass, } impl Block { @@ -74,6 +75,12 @@ impl Block { render: RenderType::SolidBlock(CubeTexture::all(BlockTexture::Cobblestone)), collision: CollisionType::Solid, raycast_collision: true, + }, + Self::TallGrass => BlockDescriptor { + name: "tall grass", + render: RenderType::CrossShape(CrossTexture::all(BlockTexture::TallGrass)), + collision: CollisionType::None, + raycast_collision: true, } } } @@ -123,12 +130,22 @@ impl CubeTexture { #[derive(Clone, Copy, Debug)] pub struct CrossTexture { pub a_front: BlockTexture, - pub b_front: BlockTexture, pub a_back: BlockTexture, + pub b_front: BlockTexture, pub b_back: BlockTexture, } impl CrossTexture { - + pub const fn same_front_back(a: BlockTexture, b: BlockTexture) -> Self { + Self { + a_front: a, + a_back: a, + b_front: b, + b_back: b, + } + } + pub const fn all(texture: BlockTexture) -> Self { + Self::same_front_back(texture, texture) + } } #[derive(Clone, Copy, Debug, PartialEq, Eq)] diff --git a/kubi/src/rendering/world.rs b/kubi/src/rendering/world.rs index 1ff8235..77a3082 100644 --- a/kubi/src/rendering/world.rs +++ b/kubi/src/rendering/world.rs @@ -44,7 +44,6 @@ pub struct ChunkVertex { } implement_vertex!(ChunkVertex, position, normal, uv, tex_index); - pub fn draw_world( mut target: NonSendSync>, chunks: UniqueView, diff --git a/kubi/src/world/mesh.rs b/kubi/src/world/mesh.rs index 8b53a58..9275730 100644 --- a/kubi/src/world/mesh.rs +++ b/kubi/src/world/mesh.rs @@ -1,84 +1,14 @@ -use strum::{EnumIter, IntoEnumIterator}; -use glam::{Vec3A, vec3a, IVec3, ivec3}; -use std::mem::discriminant; +use glam::{IVec3, ivec3}; +use strum::IntoEnumIterator; use kubi_shared::block::{Block, RenderType}; -use super::{chunk::CHUNK_SIZE, }; +use crate::world::chunk::CHUNK_SIZE; use crate::rendering::world::ChunkVertex; pub mod data; +mod builder; + use data::MeshGenData; - -#[repr(usize)] -#[derive(Clone, Copy, Debug, EnumIter)] -pub enum CubeFace { - Top = 0, - Front = 1, - Left = 2, - Right = 3, - Back = 4, - Bottom = 5, -} -const CUBE_FACE_VERTICES: [[Vec3A; 4]; 6] = [ - [vec3a(0., 1., 0.), vec3a(0., 1., 1.), vec3a(1., 1., 0.), vec3a(1., 1., 1.)], - [vec3a(0., 0., 0.), vec3a(0., 1., 0.), vec3a(1., 0., 0.), vec3a(1., 1., 0.)], - [vec3a(0., 0., 1.), vec3a(0., 1., 1.), vec3a(0., 0., 0.), vec3a(0., 1., 0.)], - [vec3a(1., 0., 0.), vec3a(1., 1., 0.), vec3a(1., 0., 1.), vec3a(1., 1., 1.)], - [vec3a(1., 0., 1.), vec3a(1., 1., 1.), vec3a(0., 0., 1.), vec3a(0., 1., 1.)], - [vec3a(0., 0., 1.), vec3a(0., 0., 0.), vec3a(1., 0., 1.), vec3a(1., 0., 0.)], -]; -const CUBE_FACE_NORMALS: [Vec3A; 6] = [ - vec3a(0., 1., 0.), - vec3a(0., 0., -1.), - vec3a(-1.,0., 0.), - vec3a(1., 0., 0.), - vec3a(0., 0., 1.), - vec3a(0., -1.,0.) -]; -const CUBE_FACE_INDICES: [u32; 6] = [0, 1, 2, 2, 1, 3]; -const UV_COORDS: [[f32; 2]; 4] = [ - [0., 0.], - [0., 1.], - [1., 0.], - [1., 1.], -]; - -#[derive(Default)] -struct MeshBuilder { - vertex_buffer: Vec, - index_buffer: Vec, - idx_counter: u32, -} -impl MeshBuilder { - pub fn new() -> Self { - Self::default() - } - - pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u8) { - let coord = coord.as_vec3a(); - let face_index = face as usize; - - //Push vertexes - let norm = CUBE_FACE_NORMALS[face_index]; - let vert = CUBE_FACE_VERTICES[face_index]; - self.vertex_buffer.reserve(4); - for i in 0..4 { - self.vertex_buffer.push(ChunkVertex { - position: (coord + vert[i]).to_array(), - normal: norm.to_array(), - uv: UV_COORDS[i], - tex_index: texture - }); - } - - //Push indices - self.index_buffer.extend_from_slice(&CUBE_FACE_INDICES.map(|x| x + self.idx_counter)); - self.idx_counter += 4; - } - - pub fn finish(self) -> (Vec, Vec) { - (self.vertex_buffer, self.index_buffer) - } -} +use builder::{CubeFace, MeshBuilder}; pub fn generate_mesh(data: MeshGenData) -> (Vec, Vec) { let get_block = |pos: IVec3| -> Block { @@ -101,22 +31,21 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec, Vec) { let mut builder = MeshBuilder::new(); - for x in 0..CHUNK_SIZE { - for y in 0..CHUNK_SIZE { - for z in 0..CHUNK_SIZE { - let coord = ivec3(x as i32, y as i32, z as i32); + for x in 0..CHUNK_SIZE as i32 { + for y in 0..CHUNK_SIZE as i32 { + for z in 0..CHUNK_SIZE as i32 { + let coord = ivec3(x, y, z); let block = get_block(coord); let descriptor = block.descriptor(); - if matches!(descriptor.render, RenderType::None) { - continue - } - for face in CubeFace::iter() { - let facing = CUBE_FACE_NORMALS[face as usize].as_ivec3(); - let facing_coord = coord + facing; - let show = discriminant(&get_block(facing_coord).descriptor().render) != discriminant(&descriptor.render); - if show { - match descriptor.render { - RenderType::SolidBlock(textures) => { + match descriptor.render { + RenderType::None => continue, + RenderType::SolidBlock(textures) => { + for face in CubeFace::iter() { + let facing_direction = face.normal(); + let facing_coord = coord + facing_direction; + let facing_descriptor = get_block(facing_coord).descriptor(); + let face_obstructed = matches!(facing_descriptor.render, RenderType::SolidBlock(_)); + if !face_obstructed { let face_texture = match face { CubeFace::Top => textures.top, CubeFace::Front => textures.front, @@ -126,9 +55,11 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec, Vec) { CubeFace::Bottom => textures.bottom, }; builder.add_face(face, coord, face_texture as u8); - }, - _ => unimplemented!() + } } + }, + RenderType::CrossShape(_) => { + todo!() } } } diff --git a/kubi/src/world/mesh/builder.rs b/kubi/src/world/mesh/builder.rs new file mode 100644 index 0000000..09bde30 --- /dev/null +++ b/kubi/src/world/mesh/builder.rs @@ -0,0 +1,89 @@ +use strum::EnumIter; +use glam::{Vec3, vec3, IVec3, ivec3}; +use crate::rendering::world::ChunkVertex; + +#[repr(usize)] +#[derive(Clone, Copy, Debug, EnumIter)] +pub enum CubeFace { + Top = 0, + Front = 1, + Left = 2, + Right = 3, + Back = 4, + Bottom = 5, +} +impl CubeFace { + pub const fn normal(self) -> IVec3 { + CUBE_FACE_NORMALS_IVEC3[self as usize] + } +} + +const CUBE_FACE_VERTICES: [[Vec3; 4]; 6] = [ + [vec3(0., 1., 0.), vec3(0., 1., 1.), vec3(1., 1., 0.), vec3(1., 1., 1.)], + [vec3(0., 0., 0.), vec3(0., 1., 0.), vec3(1., 0., 0.), vec3(1., 1., 0.)], + [vec3(0., 0., 1.), vec3(0., 1., 1.), vec3(0., 0., 0.), vec3(0., 1., 0.)], + [vec3(1., 0., 0.), vec3(1., 1., 0.), vec3(1., 0., 1.), vec3(1., 1., 1.)], + [vec3(1., 0., 1.), vec3(1., 1., 1.), vec3(0., 0., 1.), vec3(0., 1., 1.)], + [vec3(0., 0., 1.), vec3(0., 0., 0.), vec3(1., 0., 1.), vec3(1., 0., 0.)], +]; +const CUBE_FACE_NORMALS_IVEC3: [IVec3; 6] = [ + ivec3( 0, 1, 0), + ivec3( 0, 0, -1), + ivec3(-1, 0, 0), + ivec3( 1, 0, 0), + ivec3( 0, 0, 1), + ivec3( 0, -1, 0) +]; +const CUBE_FACE_NORMALS: [Vec3; 6] = [ + vec3(0., 1., 0.), + vec3(0., 0., -1.), + vec3(-1.,0., 0.), + vec3(1., 0., 0.), + vec3(0., 0., 1.), + vec3(0., -1.,0.) +]; +const CUBE_FACE_INDICES: [u32; 6] = [0, 1, 2, 2, 1, 3]; +const UV_COORDS: [[f32; 2]; 4] = [ + [0., 0.], + [0., 1.], + [1., 0.], + [1., 1.], +]; + +#[derive(Default)] +pub struct MeshBuilder { + vertex_buffer: Vec, + index_buffer: Vec, + idx_counter: u32, +} +impl MeshBuilder { + pub fn new() -> Self { + Self::default() + } + + pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u8) { + let coord = coord.as_vec3(); + let face_index = face as usize; + + //Push vertices + let norm = CUBE_FACE_NORMALS[face_index]; + let vert = CUBE_FACE_VERTICES[face_index]; + self.vertex_buffer.reserve(4); + for i in 0..4 { + self.vertex_buffer.push(ChunkVertex { + position: (coord + vert[i]).to_array(), + normal: norm.to_array(), + uv: UV_COORDS[i], + tex_index: texture + }); + } + + //Push indices + self.index_buffer.extend_from_slice(&CUBE_FACE_INDICES.map(|x| x + self.idx_counter)); + self.idx_counter += 4; + } + + pub fn finish(self) -> (Vec, Vec) { + (self.vertex_buffer, self.index_buffer) + } +} From 287baf15ea77c16821a9324396808eb73c8cd88a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 16 Feb 2023 02:00:09 +0100 Subject: [PATCH 123/160] add tall grass --- Cargo.lock | 49 ++++++++++++++++++ kubi-shared/Cargo.toml | 6 +++ kubi-shared/src/block.rs | 28 ++++++----- kubi-shared/src/worldgen.rs | 18 ++++++- kubi/Cargo.toml | 2 +- kubi/src/world/mesh.rs | 19 +++++-- kubi/src/world/mesh/builder.rs | 92 +++++++++++++++++++++++++++++++++- 7 files changed, 194 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 060d7b7..ef790c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -948,6 +948,8 @@ dependencies = [ "bincode", "bracket-noise", "glam", + "rand", + "rand_xoshiro", "shipyard", "strum", ] @@ -986,6 +988,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + [[package]] name = "libudev-sys" version = "0.1.4" @@ -1310,6 +1318,16 @@ dependencies = [ "shared_library", ] +[[package]] +name = "packed_simd_2" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" +dependencies = [ + "cfg-if", + "libm", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1377,6 +1395,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro-crate" version = "1.3.0" @@ -1411,6 +1435,19 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ + "libc", + "packed_simd_2", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", "rand_core", ] @@ -1419,6 +1456,9 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] [[package]] name = "rand_xorshift" @@ -1429,6 +1469,15 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core", +] + [[package]] name = "raw-window-handle" version = "0.4.3" diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index b615b4f..b16a3b3 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -13,3 +13,9 @@ strum = { version = "0.24", features = ["derive"] } bincode = "2.0.0-rc" anyhow = "1.0" bracket-noise = "0.8" +rand = { version = "0.8", default_features = false, features = ["std", "min_const_gen"] } +rand_xoshiro = "0.6" + +[features] +default = [] +nightly = ["rand/nightly", "rand/simd_support"] diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index e42c367..76a126b 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -128,23 +128,27 @@ impl CubeTexture { } #[derive(Clone, Copy, Debug)] -pub struct CrossTexture { - pub a_front: BlockTexture, - pub a_back: BlockTexture, - pub b_front: BlockTexture, - pub b_back: BlockTexture, +pub struct CrossTextureSides { + pub front: BlockTexture, + pub back: BlockTexture } -impl CrossTexture { - pub const fn same_front_back(a: BlockTexture, b: BlockTexture) -> Self { +impl CrossTextureSides { + pub const fn all(texture: BlockTexture) -> Self { Self { - a_front: a, - a_back: a, - b_front: b, - b_back: b, + front: texture, + back: texture } } +} + +#[derive(Clone, Copy, Debug)] +pub struct CrossTexture(pub CrossTextureSides, pub CrossTextureSides); +impl CrossTexture { pub const fn all(texture: BlockTexture) -> Self { - Self::same_front_back(texture, texture) + Self( + CrossTextureSides::all(texture), + CrossTextureSides::all(texture) + ) } } diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index ca2df3e..57cb98c 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -1,5 +1,7 @@ -use glam::{IVec3, ivec3}; use bracket_noise::prelude::*; +use rand::prelude::*; +use glam::{IVec3, ivec3}; +use rand_xoshiro::Xoshiro256StarStar; use crate::{ chunk::{BlockData, CHUNK_SIZE}, block::Block @@ -41,6 +43,14 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { elevation_noise.set_fractal_octaves(1); elevation_noise.set_frequency(0.001); + let mut rng = Xoshiro256StarStar::seed_from_u64( + seed + ^ ((chunk_position.x as u32 as u64) << 0) + ^ ((chunk_position.y as u32 as u64) << 16) + ^ ((chunk_position.z as u32 as u64) << 32) + ); + let tall_grass_map: [[u8; CHUNK_SIZE]; CHUNK_SIZE] = rng.gen(); + // let mut cave_noise = FastNoise::seeded(seed.rotate_left(1)); // cave_noise.set_fractal_type(FractalType::FBM); // cave_noise.set_fractal_octaves(2); @@ -75,6 +85,12 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { if let Some(y) = local_y_position(height, chunk_position) { blocks[x][y][z] = Block::Grass; } + //place tall grass + if tall_grass_map[x][z] < 10 { + if let Some(y) = local_y_position(height + 1, chunk_position) { + blocks[x][y][z] = Block::TallGrass; + } + } } } diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 56f5841..78a8b35 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -26,4 +26,4 @@ winapi = { version = "0.3" } [features] default = [] -unstable = ["glam/core-simd"] +nightly = ["glam/core-simd", "kubi-shared/nightly"] diff --git a/kubi/src/world/mesh.rs b/kubi/src/world/mesh.rs index 9275730..4f81538 100644 --- a/kubi/src/world/mesh.rs +++ b/kubi/src/world/mesh.rs @@ -8,7 +8,7 @@ pub mod data; mod builder; use data::MeshGenData; -use builder::{CubeFace, MeshBuilder}; +use builder::{MeshBuilder, CubeFace, DiagonalFace}; pub fn generate_mesh(data: MeshGenData) -> (Vec, Vec) { let get_block = |pos: IVec3| -> Block { @@ -58,9 +58,20 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec, Vec) { } } }, - RenderType::CrossShape(_) => { - todo!() - } + RenderType::CrossShape(textures) => { + builder.add_diagonal_face( + coord, + DiagonalFace::LeftZ, + textures.0.front as u8, + textures.0.back as u8 + ); + builder.add_diagonal_face( + coord, + DiagonalFace::RigthZ, + textures.1.front as u8, + textures.1.back as u8 + ); + }, } } } diff --git a/kubi/src/world/mesh/builder.rs b/kubi/src/world/mesh/builder.rs index 09bde30..ed1ffd7 100644 --- a/kubi/src/world/mesh/builder.rs +++ b/kubi/src/world/mesh/builder.rs @@ -2,14 +2,16 @@ use strum::EnumIter; use glam::{Vec3, vec3, IVec3, ivec3}; use crate::rendering::world::ChunkVertex; +const INV_SQRT_2: f32 = 0.70710678118655; // 1 / 2.sqrt() + #[repr(usize)] #[derive(Clone, Copy, Debug, EnumIter)] pub enum CubeFace { Top = 0, - Front = 1, + Front = 4, Left = 2, Right = 3, - Back = 4, + Back = 1, Bottom = 5, } impl CubeFace { @@ -43,6 +45,40 @@ const CUBE_FACE_NORMALS: [Vec3; 6] = [ vec3(0., -1.,0.) ]; const CUBE_FACE_INDICES: [u32; 6] = [0, 1, 2, 2, 1, 3]; + +#[repr(usize)] +pub enum DiagonalFace { + RigthZ = 0, + LeftZ = 1, +} +const CROSS_FACES: [[Vec3; 4]; 2] = [ + [ + vec3(0., 0., 0.), + vec3(0., 1., 0.), + vec3(1., 0., 1.), + vec3(1., 1., 1.), + ], + [ + vec3(0., 0., 1.), + vec3(0., 1., 1.), + vec3(1., 0., 0.), + vec3(1., 1., 0.), + ] +]; +const CROSS_FACE_NORMALS: [Vec3; 2] = [ + vec3(-INV_SQRT_2, 0., INV_SQRT_2), + vec3(INV_SQRT_2, 0., INV_SQRT_2), +]; +const CROSS_FACE_NORMALS_BACK: [Vec3; 2] = [ + vec3(INV_SQRT_2, 0., -INV_SQRT_2), + vec3(-INV_SQRT_2, 0., -INV_SQRT_2), +]; +const CROSS_FACE_INDICES: [u32; 12] = [ + 0, 1, 2, 2, 1, 3, //Front side + 6, 5, 4, 7, 5, 6, //Back side +]; + + const UV_COORDS: [[f32; 2]; 4] = [ [0., 0.], [0., 1.], @@ -80,9 +116,61 @@ impl MeshBuilder { //Push indices self.index_buffer.extend_from_slice(&CUBE_FACE_INDICES.map(|x| x + self.idx_counter)); + + //Increment idx counter self.idx_counter += 4; } + pub fn add_diagonal_face(&mut self, coord: IVec3, face_type: DiagonalFace, front_texture: u8, back_texture: u8) { + //Push vertices + let face_type = face_type as usize; + let vertices = CROSS_FACES[face_type]; + let normal_front = CROSS_FACE_NORMALS[face_type].to_array(); + let normal_back = CROSS_FACE_NORMALS[face_type].to_array(); + self.vertex_buffer.reserve(8); + for i in 0..4 { //push front vertices + self.vertex_buffer.push(ChunkVertex { + position: (coord.as_vec3() + vertices[i]).to_array(), + normal: normal_front, + uv: UV_COORDS[i], + tex_index: front_texture + }) + } + for i in 0..4 { //push back vertices + self.vertex_buffer.push(ChunkVertex { + position: (coord.as_vec3() + vertices[i]).to_array(), + normal: normal_back, + uv: UV_COORDS[i], + tex_index: back_texture + }) + } + + //Push indices + self.index_buffer.extend_from_slice(&CROSS_FACE_INDICES.map(|x| x + self.idx_counter)); + + //Increment idx counter + self.idx_counter += 8; + } + + pub fn add_model(&mut self, position: Vec3, vertices: &[ChunkVertex], indices: Option<&[u32]>) { + //push vertices + self.vertex_buffer.extend(vertices.iter().map(|vertex| { + let mut vertex = *vertex; + vertex.position[0] += position.x; + vertex.position[0] += position.y; + vertex.position[0] += position.z; + vertex + })); + //push indices + if let Some(indices) = indices { + self.index_buffer.extend(indices.iter().map(|x| x + self.idx_counter)); + } else { + self.index_buffer.extend(0..(self.vertex_buffer.len() as u32)); + } + //increment idx counter + self.idx_counter += vertices.len() as u32; + } + pub fn finish(self) -> (Vec, Vec) { (self.vertex_buffer, self.index_buffer) } From 7612ea8d8ddab5a180f2cb49d0b18298f9d703ff Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 16 Feb 2023 02:44:21 +0100 Subject: [PATCH 124/160] Add planks --- assets/blocks/planks.png | Bin 0 -> 247 bytes kubi-shared/src/block.rs | 10 ++++++- kubi/src/block_placement.rs | 58 +++++++++++++++++++++++++++++++----- kubi/src/control_flow.rs | 4 +-- kubi/src/input.rs | 8 ++--- kubi/src/main.rs | 4 +-- kubi/src/player.rs | 4 ++- kubi/src/prefabs.rs | 1 + kubi/src/world/raycast.rs | 2 +- 9 files changed, 72 insertions(+), 19 deletions(-) create mode 100644 assets/blocks/planks.png diff --git a/assets/blocks/planks.png b/assets/blocks/planks.png new file mode 100644 index 0000000000000000000000000000000000000000..c06e26999e43bce2e348a93a8a96dd3420909c2e GIT binary patch literal 247 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFxj zZ|fR+ZkDW^Ix}>q~Qo{1SG5>a m_24=^^Dl2JUrqjA{+GeOmgnOR8-+TcwG5uFelF{r5}E)>Bv(5C literal 0 HcmV?d00001 diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index 76a126b..7244b2c 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -18,6 +18,7 @@ pub enum BlockTexture { Snow, GrassSideSnow, Cobblestone, + Planks, } #[derive(Encode, Decode, Clone, Copy, Debug, PartialEq, Eq, EnumIter)] @@ -30,6 +31,7 @@ pub enum Block { Sand, Cobblestone, TallGrass, + Planks, } impl Block { @@ -81,7 +83,13 @@ impl Block { render: RenderType::CrossShape(CrossTexture::all(BlockTexture::TallGrass)), collision: CollisionType::None, raycast_collision: true, - } + }, + Self::Planks => BlockDescriptor { + name: "planks", + render: RenderType::SolidBlock(CubeTexture::all(BlockTexture::Planks)), + collision: CollisionType::Solid, + raycast_collision: true, + }, } } } diff --git a/kubi/src/block_placement.rs b/kubi/src/block_placement.rs index 0a08390..36605d2 100644 --- a/kubi/src/block_placement.rs +++ b/kubi/src/block_placement.rs @@ -1,14 +1,47 @@ -use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut}; +use shipyard::{UniqueViewMut, UniqueView, View, IntoIter, ViewMut, EntitiesViewMut, Component, Workload, IntoWorkload}; +use glium::glutin::event::VirtualKeyCode; use kubi_shared::block::Block; use crate::{ player::MainPlayer, - world::{raycast::LookingAtBlock, queue::{BlockUpdateQueue, BlockUpdateEvent}}, - input::{Inputs, PrevInputs}, + world::{raycast::{LookingAtBlock, RAYCAST_STEP}, queue::{BlockUpdateQueue, BlockUpdateEvent}}, + input::{Inputs, PrevInputs, RawKbmInputState}, events::{EventComponent, player_actions::PlayerActionEvent}, }; -pub fn block_placement_system( +#[derive(Component)] +pub struct PlayerHolding(pub Block); +impl Default for PlayerHolding { + fn default() -> Self { + Self(Block::Cobblestone) + } +} + +const BLOCK_KEY_MAP: &[(VirtualKeyCode, Block)] = &[ + (VirtualKeyCode::Key1, Block::Cobblestone), + (VirtualKeyCode::Key2, Block::Planks), + (VirtualKeyCode::Key3, Block::Dirt), + (VirtualKeyCode::Key4, Block::Grass), + (VirtualKeyCode::Key5, Block::Sand), + (VirtualKeyCode::Key6, Block::Stone), +]; + +fn pick_block_with_number_keys( main_player: View, + mut holding: ViewMut, + input: UniqueView, +) { + let Some((_, mut holding)) = (&main_player, &mut holding).iter().next() else { return }; + for &(key, block) in BLOCK_KEY_MAP { + if input.keyboard_state.contains(&key) { + holding.0 = block; + return + } + } +} + +fn block_placement_system( + main_player: View, + holding: View, raycast: View, input: UniqueView, prev_input: UniqueView, @@ -20,12 +53,14 @@ pub fn block_placement_system( let action_place = input.action_b && !prev_input.0.action_b; let action_break = input.action_a && !prev_input.0.action_a; if action_place ^ action_break { - //get raycast info - let Some(ray) = (&main_player, &raycast).iter().next().unwrap().1/**/.0 else { return }; + //get components + let Some((_, ray, block)) = (&main_player, &raycast, &holding).iter().next() else { return }; + let Some(ray) = ray.0 else { return }; //get coord and block type let (place_position, place_block) = if action_place { - let position = (ray.position - ray.direction * 0.251).floor().as_ivec3(); - (position, Block::Cobblestone) + if block.0 == Block::Air { return } + let position = (ray.position - ray.direction * (RAYCAST_STEP + 0.001)).floor().as_ivec3(); + (position, block.0) } else { (ray.block_position, Block::Air) }; @@ -44,3 +79,10 @@ pub fn block_placement_system( ); } } + +pub fn update_block_placement() -> Workload { + ( + pick_block_with_number_keys, + block_placement_system + ).into_workload() +} diff --git a/kubi/src/control_flow.rs b/kubi/src/control_flow.rs index 253dbdb..9dad6e1 100644 --- a/kubi/src/control_flow.rs +++ b/kubi/src/control_flow.rs @@ -1,12 +1,12 @@ use shipyard::{UniqueView, UniqueViewMut, Unique, AllStoragesView}; use glium::glutin::{event::VirtualKeyCode, event_loop::ControlFlow}; -use crate::input::RawInputState; +use crate::input::RawKbmInputState; #[derive(Unique)] pub struct SetControlFlow(pub Option); pub fn exit_on_esc( - raw_inputs: UniqueView, + raw_inputs: UniqueView, mut control_flow: UniqueViewMut ) { if raw_inputs.keyboard_state.contains(&VirtualKeyCode::Escape) { diff --git a/kubi/src/input.rs b/kubi/src/input.rs index 6b92835..fe9fd57 100644 --- a/kubi/src/input.rs +++ b/kubi/src/input.rs @@ -18,7 +18,7 @@ pub struct Inputs { pub struct PrevInputs(pub Inputs); #[derive(Unique, Clone, Default, Debug)] -pub struct RawInputState { +pub struct RawKbmInputState { pub keyboard_state: HashSet>, pub button_state: [bool; 32], pub mouse_delta: DVec2 @@ -35,7 +35,7 @@ pub struct ActiveGamepad(Option); fn process_events( device_events: View, - mut input_state: UniqueViewMut, + mut input_state: UniqueViewMut, ) { input_state.mouse_delta = DVec2::ZERO; for event in device_events.iter() { @@ -79,7 +79,7 @@ fn input_start( } fn update_input_state ( - raw_inputs: UniqueView, + raw_inputs: UniqueView, mut inputs: UniqueViewMut, ) { inputs.movement += Vec2::new( @@ -123,7 +123,7 @@ pub fn init_input ( storages.add_unique(ActiveGamepad::default()); storages.add_unique(Inputs::default()); storages.add_unique(PrevInputs::default()); - storages.add_unique(RawInputState::default()); + storages.add_unique(RawKbmInputState::default()); } pub fn process_inputs() -> Workload { diff --git a/kubi/src/main.rs b/kubi/src/main.rs index c02f929..472d3c0 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -72,7 +72,7 @@ use rendering::{ world::draw_world, world::draw_current_chunk_border, }; -use block_placement::block_placement_system; +use block_placement::update_block_placement; use delta_time::{DeltaTime, init_delta_time}; use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow}; @@ -124,7 +124,7 @@ fn update() -> Workload { update_controllers, generate_move_events, update_raycasts, - block_placement_system, + update_block_placement, apply_queued_blocks, ).into_workload().run_if(is_ingame), compute_cameras, diff --git a/kubi/src/player.rs b/kubi/src/player.rs index a6afaed..cc1e705 100644 --- a/kubi/src/player.rs +++ b/kubi/src/player.rs @@ -3,7 +3,8 @@ use crate::{ transform::Transform, camera::Camera, fly_controller::FlyController, - world::raycast::LookingAtBlock, + world::raycast::LookingAtBlock, + block_placement::PlayerHolding, }; #[derive(Component)] @@ -23,5 +24,6 @@ pub fn spawn_player ( Camera::default(), FlyController, LookingAtBlock::default(), + PlayerHolding::default(), )); } diff --git a/kubi/src/prefabs.rs b/kubi/src/prefabs.rs index 1fc81b5..c1ec11b 100644 --- a/kubi/src/prefabs.rs +++ b/kubi/src/prefabs.rs @@ -30,6 +30,7 @@ impl AssetPaths for BlockTexture { Self::Snow => "snow.png", Self::GrassSideSnow => "grass_side_snow.png", Self::Cobblestone => "cobblestone.png", + Self::Planks => "planks.png", } } } diff --git a/kubi/src/world/raycast.rs b/kubi/src/world/raycast.rs index c545595..c0d1c3c 100644 --- a/kubi/src/world/raycast.rs +++ b/kubi/src/world/raycast.rs @@ -4,7 +4,7 @@ use kubi_shared::block::Block; use crate::transform::Transform; use super::ChunkStorage; -const RAYCAST_STEP: f32 = 0.25; +pub const RAYCAST_STEP: f32 = 0.25; #[derive(Clone, Copy, Debug)] pub struct RaycastReport { From 626e9e654d22f93a4d1acc37ba2947b2bcdd99d1 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 16 Feb 2023 02:57:04 +0100 Subject: [PATCH 125/160] rotate elevation noise --- kubi-shared/src/worldgen.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 57cb98c..63a3dff 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -38,7 +38,7 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { height_noise.set_fractal_octaves(4); height_noise.set_frequency(0.003); - let mut elevation_noise = FastNoise::seeded(seed); + let mut elevation_noise = FastNoise::seeded(seed.rotate_left(1)); elevation_noise.set_fractal_type(FractalType::FBM); elevation_noise.set_fractal_octaves(1); elevation_noise.set_frequency(0.001); From f8732abb5d07f20b816fdad7c1af47ebb3e4ac83 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 16 Feb 2023 03:54:57 +0100 Subject: [PATCH 126/160] Placement queue, binary transparency, WIP trees --- kubi-shared/src/block.rs | 22 +++++++++++++++++++ kubi-shared/src/worldgen.rs | 42 ++++++++++++++++++++++++++++++------- kubi/src/block_placement.rs | 1 + kubi/src/world/loading.rs | 16 +++++++++++--- kubi/src/world/mesh.rs | 8 +++++-- kubi/src/world/tasks.rs | 19 ++++++++++++----- 6 files changed, 91 insertions(+), 17 deletions(-) diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index 7244b2c..dae5489 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -32,6 +32,9 @@ pub enum Block { Cobblestone, TallGrass, Planks, + Torch, + Wood, + Leaf, } impl Block { @@ -90,6 +93,24 @@ impl Block { collision: CollisionType::Solid, raycast_collision: true, }, + Self::Torch => BlockDescriptor { + name: "torch", + render: RenderType::CrossShape(CrossTexture::all(BlockTexture::Torch)), + collision: CollisionType::None, + raycast_collision: true, + }, + Self::Wood => BlockDescriptor { + name: "leaf", + render: RenderType::SolidBlock(CubeTexture::horizontal_vertical(BlockTexture::Wood, BlockTexture::WoodTop)), + collision: CollisionType::Solid, + raycast_collision: true, + }, + Self::Leaf => BlockDescriptor { + name: "leaf", + render: RenderType::BinaryTransparency(CubeTexture::all(BlockTexture::Leaf)), + collision: CollisionType::Solid, + raycast_collision: true, + }, } } } @@ -170,5 +191,6 @@ pub enum CollisionType { pub enum RenderType { None, SolidBlock(CubeTexture), + BinaryTransparency(CubeTexture), CrossShape(CrossTexture), } diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 63a3dff..782ba91 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -29,10 +29,27 @@ fn local_y_position(height: i32, chunk_position: IVec3) -> Option { (0..CHUNK_SIZE as i32).contains(&position).then_some(position as usize) } -pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { +pub struct QueuedBlock { + pub position: IVec3, + pub block_type: Block, +} + +pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec) { let offset = chunk_position * CHUNK_SIZE as i32; let mut blocks = Box::new([[[Block::Air; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]); - + let mut queue = Vec::with_capacity(0); + + let mut smart_place = |blocks: &mut BlockData, position: IVec3, block: Block| { + if position.to_array().iter().any(|&x| !(0..CHUNK_SIZE).contains(&(x as usize))) { + queue.push(QueuedBlock { + position: offset + position, + block_type: block + }); + } else { + blocks[position.x as usize][position.y as usize][position.z as usize] = block; + } + }; + let mut height_noise = FastNoise::seeded(seed); height_noise.set_fractal_type(FractalType::FBM); height_noise.set_fractal_octaves(4); @@ -46,10 +63,10 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { let mut rng = Xoshiro256StarStar::seed_from_u64( seed ^ ((chunk_position.x as u32 as u64) << 0) - ^ ((chunk_position.y as u32 as u64) << 16) ^ ((chunk_position.z as u32 as u64) << 32) ); - let tall_grass_map: [[u8; CHUNK_SIZE]; CHUNK_SIZE] = rng.gen(); + let rng_map_a: [[f32; CHUNK_SIZE]; CHUNK_SIZE] = rng.gen(); + let rng_map_b: [[f32; CHUNK_SIZE]; CHUNK_SIZE] = rng.gen(); // let mut cave_noise = FastNoise::seeded(seed.rotate_left(1)); // cave_noise.set_fractal_type(FractalType::FBM); @@ -86,11 +103,22 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { blocks[x][y][z] = Block::Grass; } //place tall grass - if tall_grass_map[x][z] < 10 { + if rng_map_a[x][z] < 0.03 { if let Some(y) = local_y_position(height + 1, chunk_position) { blocks[x][y][z] = Block::TallGrass; } } + //place trees! + if rng_map_a[x][z] < 0.001 { + if let Some(y) = local_y_position(height + 1, chunk_position) { + let tree_pos = ivec3(x as i32, y as i32, z as i32); + let tree_height = 6 + (rng_map_b[x][z] * 6.).round() as i32; + for tree_y in 0..tree_height { + smart_place(&mut blocks, tree_pos + IVec3::Y * tree_y, Block::Wood); + } + smart_place(&mut blocks, tree_pos + IVec3::Y * tree_height, Block::Leaf); + } + } } } @@ -111,8 +139,8 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { // } } - blocks - + (blocks, queue) + // let mut cave_noise = FastNoise::seeded(seed); // cave_noise.set_fractal_type(FractalType::FBM); // cave_noise.set_frequency(0.1); diff --git a/kubi/src/block_placement.rs b/kubi/src/block_placement.rs index 36605d2..7b2b93c 100644 --- a/kubi/src/block_placement.rs +++ b/kubi/src/block_placement.rs @@ -23,6 +23,7 @@ const BLOCK_KEY_MAP: &[(VirtualKeyCode, Block)] = &[ (VirtualKeyCode::Key4, Block::Grass), (VirtualKeyCode::Key5, Block::Sand), (VirtualKeyCode::Key6, Block::Stone), + (VirtualKeyCode::Key7, Block::Torch), ]; fn pick_block_with_number_keys( diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index 18c0172..8866058 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -11,7 +11,8 @@ use crate::{ use super::{ ChunkStorage, ChunkMeshStorage, chunk::{Chunk, DesiredChunkState, CHUNK_SIZE, ChunkMesh, CurrentChunkState, ChunkData}, - tasks::{ChunkTaskManager, ChunkTaskResponse, ChunkTask}, + tasks::{ChunkTaskManager, ChunkTaskResponse, ChunkTask}, + queue::{BlockUpdateQueue, BlockUpdateEvent}, }; const MAX_CHUNK_OPS_INGAME: usize = 6; @@ -170,12 +171,13 @@ fn process_completed_tasks( mut world: UniqueViewMut, mut meshes: NonSendSync>, renderer: NonSendSync>, - state: UniqueView + state: UniqueView, + mut queue: UniqueViewMut, ) { let mut ops: usize = 0; while let Some(res) = task_manager.receive() { match res { - ChunkTaskResponse::LoadedChunk { position, chunk_data } => { + ChunkTaskResponse::LoadedChunk { position, chunk_data, queued } => { //check if chunk exists let Some(chunk) = world.chunks.get_mut(&position) else { log::warn!("blocks data discarded: chunk doesn't exist"); @@ -196,6 +198,14 @@ fn process_completed_tasks( //update chunk state chunk.current_state = CurrentChunkState::Loaded; + //push queued blocks + for event in queued { + queue.push(BlockUpdateEvent { + position: event.position, + value: event.block_type, + }); + } + //increase ops counter ops += 1; }, diff --git a/kubi/src/world/mesh.rs b/kubi/src/world/mesh.rs index 4f81538..93cd762 100644 --- a/kubi/src/world/mesh.rs +++ b/kubi/src/world/mesh.rs @@ -39,12 +39,16 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec, Vec) { let descriptor = block.descriptor(); match descriptor.render { RenderType::None => continue, - RenderType::SolidBlock(textures) => { + RenderType::SolidBlock(textures) | RenderType::BinaryTransparency(textures) => { for face in CubeFace::iter() { let facing_direction = face.normal(); let facing_coord = coord + facing_direction; let facing_descriptor = get_block(facing_coord).descriptor(); - let face_obstructed = matches!(facing_descriptor.render, RenderType::SolidBlock(_)); + let face_obstructed = match descriptor.render { + RenderType::SolidBlock(_) => matches!(facing_descriptor.render, RenderType::SolidBlock(_)), + RenderType::BinaryTransparency(_) => matches!(facing_descriptor.render, RenderType::SolidBlock(_) | RenderType::BinaryTransparency(_)), + _ => unreachable!(), + }; if !face_obstructed { let face_texture = match face { CubeFace::Top => textures.top, diff --git a/kubi/src/world/tasks.rs b/kubi/src/world/tasks.rs index 82da68a..60b39e0 100644 --- a/kubi/src/world/tasks.rs +++ b/kubi/src/world/tasks.rs @@ -1,6 +1,9 @@ use flume::{Sender, Receiver}; use glam::IVec3; -use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; +use kubi_shared::{ + networking::messages::{ClientToServerMessage, ServerToClientMessage}, + worldgen::QueuedBlock +}; use shipyard::{Unique, UniqueView, View, IntoIter}; use rayon::{ThreadPool, ThreadPoolBuilder}; use super::{ @@ -8,7 +11,10 @@ use super::{ mesh::{generate_mesh, data::MeshGenData}, worldgen::generate_world, }; -use crate::{rendering::world::ChunkVertex, networking::{UdpClient, NetworkEvent}}; +use crate::{ + rendering::world::ChunkVertex, + networking::{UdpClient, NetworkEvent} +}; use kubi_udp::client::ClientEvent; pub enum ChunkTask { @@ -25,6 +31,7 @@ pub enum ChunkTaskResponse { LoadedChunk { position: IVec3, chunk_data: BlockData, + queued: Vec }, GeneratedMesh { position: IVec3, @@ -59,8 +66,8 @@ impl ChunkTaskManager { ChunkTaskResponse::GeneratedMesh { position, vertices, indexes } }, ChunkTask::LoadChunk { position, seed } => { - let chunk_data = generate_world(position, seed); - ChunkTaskResponse::LoadedChunk { position, chunk_data } + let (chunk_data, queued) = generate_world(position, seed); + ChunkTaskResponse::LoadedChunk { position, chunk_data, queued } } }); }); @@ -97,7 +104,9 @@ pub fn inject_network_responses_into_manager_queue( if let ClientEvent::MessageReceived(ServerToClientMessage::ChunkResponse { chunk, data }) = &event.0 { let position = IVec3::from_array(*chunk); manager.add_sussy_response(ChunkTaskResponse::LoadedChunk { - position, chunk_data: data.clone() + position, + chunk_data: data.clone(), + queued: Vec::with_capacity(0) }); } } From f9b4628b490e11433b2d330e808b692c3c3f2548 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 16 Feb 2023 04:05:27 +0100 Subject: [PATCH 127/160] better trees --- kubi-shared/src/worldgen.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 782ba91..7514f6f 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -1,6 +1,6 @@ use bracket_noise::prelude::*; use rand::prelude::*; -use glam::{IVec3, ivec3}; +use glam::{IVec3, ivec3, Vec3Swizzles, IVec2}; use rand_xoshiro::Xoshiro256StarStar; use crate::{ chunk::{BlockData, CHUNK_SIZE}, @@ -41,8 +41,12 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec (BlockData, Vec Date: Thu, 16 Feb 2023 04:08:00 +0100 Subject: [PATCH 128/160] even better trees --- kubi-shared/src/worldgen.rs | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 7514f6f..1ba5515 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -120,14 +120,30 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec Date: Fri, 17 Feb 2023 22:03:45 +0100 Subject: [PATCH 129/160] soft updates --- kubi-shared/src/worldgen.rs | 4 +++- kubi/src/block_placement.rs | 1 + kubi/src/rendering/world.rs | 2 +- kubi/src/world/loading.rs | 1 + kubi/src/world/queue.rs | 4 +++- 5 files changed, 9 insertions(+), 3 deletions(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 1ba5515..7171773 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -118,7 +118,9 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec Date: Fri, 17 Feb 2023 22:25:53 +0100 Subject: [PATCH 130/160] Better tree gen --- kubi-shared/src/worldgen.rs | 14 ++++++++------ kubi/src/rendering/world.rs | 2 +- kubi/src/world/queue.rs | 3 +++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 7171773..1227a87 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -114,14 +114,16 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec Date: Fri, 17 Feb 2023 22:44:01 +0100 Subject: [PATCH 131/160] caves --- kubi-shared/src/worldgen.rs | 44 +++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 1227a87..4cf66be 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -64,6 +64,16 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec (BlockData, Vec (BlockData, Vec Date: Fri, 17 Feb 2023 23:05:55 +0100 Subject: [PATCH 132/160] cave generation (no scaling yet!) --- kubi-shared/src/worldgen.rs | 56 ++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 4cf66be..0de0826 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -74,6 +74,11 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec (BlockData, Vec (BlockData, Vec (BlockData, Vec (BlockData, Vec Date: Sat, 18 Feb 2023 00:37:17 +0100 Subject: [PATCH 133/160] improve worldgen --- assets/blocks/solid_water.png | Bin 0 -> 210 bytes kubi-shared/src/block.rs | 7 ++ kubi-shared/src/worldgen.rs | 126 ++++++++++++++++++++++++++-------- 3 files changed, 106 insertions(+), 27 deletions(-) create mode 100644 assets/blocks/solid_water.png diff --git a/assets/blocks/solid_water.png b/assets/blocks/solid_water.png new file mode 100644 index 0000000000000000000000000000000000000000..7505981b6aed71a697a08740a2c146c12b84a8b4 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF~9{M`SSr1K(i~W;~w1A_XWI BlockDescriptor { + name: "marker", + render: RenderType::None, + collision: CollisionType::None, + raycast_collision: false, + }, Self::Stone => BlockDescriptor { name: "stone", render: RenderType::SolidBlock(CubeTexture::all(BlockTexture::Stone)), diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 0de0826..954293e 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -63,7 +63,7 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec (BlockData, Vec (BlockData, Vec 0.4 { + let raw_ravine_value = ravine_nose_line.get_noise(noise_x, noise_y); + if (-0.0125..0.0125).contains(&(raw_ravine_value.powi(2))) { + is_surface = false; + height -= (100. * (0.0125 - raw_ravine_value.powi(2)) * (1. / 0.0125)).round() as i32; + } + } + } height }; //add to heightmap - heightmap[x as usize][z as usize] = height; - //place dirt - for y in 0..local_height(height, chunk_position) { - blocks[x][y][z] = Block::Dirt; - within_heightmap = true; - } - //place stone - for y in 0..local_height(height - 5 - (raw_heightmap_value * 5.) as i32, chunk_position) { - blocks[x][y][z] = Block::Stone; - within_heightmap = true; - } - //place grass - if let Some(y) = local_y_position(height, chunk_position) { - blocks[x][y][z] = Block::Grass; + if is_surface { + deco_heightmap[x as usize][z as usize] = Some(height); + //place dirt + for y in 0..local_height(height, chunk_position) { + blocks[x][y][z] = Block::Dirt; + within_heightmap = true; + } + //place stone + for y in 0..local_height(height - 5 - (raw_heightmap_value * 5.) as i32, chunk_position) { + blocks[x][y][z] = Block::Stone; + within_heightmap = true; + } + //place grass + if let Some(y) = local_y_position(height, chunk_position) { + blocks[x][y][z] = Block::Grass; + within_heightmap = true; + } + } else { + for y in 0..local_height(height, chunk_position) { + blocks[x][y][z] = Block::Stone; + within_heightmap = true; + } } } } @@ -128,15 +173,30 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec (BlockData, Vec (BlockData, Vec (BlockData, Vec Date: Sat, 18 Feb 2023 00:38:09 +0100 Subject: [PATCH 134/160] fix order --- kubi-shared/src/worldgen.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 954293e..382b094 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -119,18 +119,21 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec 0.4 { let raw_ravine_value = ravine_nose_line.get_noise(noise_x, noise_y); if (-0.0125..0.0125).contains(&(raw_ravine_value.powi(2))) { From fc783d52dcac7bdf0f21a8c535fb2cfbde67541e Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sat, 18 Feb 2023 00:58:31 +0100 Subject: [PATCH 135/160] river generation --- kubi-shared/src/block.rs | 8 ++++++++ kubi-shared/src/worldgen.rs | 33 +++++++++++++++++++++++++++------ kubi/src/prefabs.rs | 1 + 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index 558e1df..c428078 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -19,6 +19,7 @@ pub enum BlockTexture { GrassSideSnow, Cobblestone, Planks, + WaterSolid, } #[derive(Encode, Decode, Clone, Copy, Debug, PartialEq, Eq, EnumIter)] @@ -36,6 +37,7 @@ pub enum Block { Torch, Wood, Leaf, + Water, } impl Block { @@ -118,6 +120,12 @@ impl Block { collision: CollisionType::Solid, raycast_collision: true, }, + Self::Water => BlockDescriptor { + name: "water", + render: RenderType::BinaryTransparency(CubeTexture::all(BlockTexture::WaterSolid)), + collision: CollisionType::None, + raycast_collision: false, + }, } } } diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 382b094..09cb993 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -125,11 +125,13 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec (BlockData, Vec "grass_side_snow.png", Self::Cobblestone => "cobblestone.png", Self::Planks => "planks.png", + Self::WaterSolid => "solid_water.png", } } } From ce687e8d36fed8592112978b406283ae87ef7dab Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sat, 18 Feb 2023 01:04:54 +0100 Subject: [PATCH 136/160] changes to binary transparency meshing --- kubi-shared/src/block.rs | 2 +- kubi/src/block_placement.rs | 1 + kubi/src/world/mesh.rs | 11 +++++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index c428078..5afc8db 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -124,7 +124,7 @@ impl Block { name: "water", render: RenderType::BinaryTransparency(CubeTexture::all(BlockTexture::WaterSolid)), collision: CollisionType::None, - raycast_collision: false, + raycast_collision: true, }, } } diff --git a/kubi/src/block_placement.rs b/kubi/src/block_placement.rs index 324a08c..19cfa8f 100644 --- a/kubi/src/block_placement.rs +++ b/kubi/src/block_placement.rs @@ -24,6 +24,7 @@ const BLOCK_KEY_MAP: &[(VirtualKeyCode, Block)] = &[ (VirtualKeyCode::Key5, Block::Sand), (VirtualKeyCode::Key6, Block::Stone), (VirtualKeyCode::Key7, Block::Torch), + (VirtualKeyCode::Key8, Block::Leaf), ]; fn pick_block_with_number_keys( diff --git a/kubi/src/world/mesh.rs b/kubi/src/world/mesh.rs index 93cd762..79c2aa7 100644 --- a/kubi/src/world/mesh.rs +++ b/kubi/src/world/mesh.rs @@ -43,10 +43,17 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec, Vec) { for face in CubeFace::iter() { let facing_direction = face.normal(); let facing_coord = coord + facing_direction; - let facing_descriptor = get_block(facing_coord).descriptor(); + let facing_block = get_block(facing_coord); + let facing_descriptor = facing_block.descriptor(); let face_obstructed = match descriptor.render { RenderType::SolidBlock(_) => matches!(facing_descriptor.render, RenderType::SolidBlock(_)), - RenderType::BinaryTransparency(_) => matches!(facing_descriptor.render, RenderType::SolidBlock(_) | RenderType::BinaryTransparency(_)), + RenderType::BinaryTransparency(_) => { + match facing_descriptor.render { + RenderType::SolidBlock(_) => true, + RenderType::BinaryTransparency(_) => block == facing_block, + _ => false, + } + }, _ => unreachable!(), }; if !face_obstructed { From 3f6abb75fdeae91601e8ce9c69550937a4f095c6 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 00:34:26 +0100 Subject: [PATCH 137/160] Upgrade packages --- Cargo.lock | 139 ++++++++++++++++++----------------------- kubi-server/Cargo.toml | 2 +- kubi-shared/Cargo.toml | 2 +- kubi/Cargo.toml | 2 +- 4 files changed, 64 insertions(+), 81 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef790c0..4024f65 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -150,9 +150,9 @@ checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" [[package]] name = "bytemuck" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c041d3eab048880cb0b86b256447da3f18859a163c3b8d8893f4e6368abe6393" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" [[package]] name = "byteorder" @@ -304,9 +304,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" dependencies = [ "cfg-if", "crossbeam-utils", @@ -314,9 +314,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" dependencies = [ "cfg-if", "crossbeam-epoch", @@ -325,22 +325,22 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.13" +version = "0.9.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" +checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset 0.7.1", + "memoffset 0.8.0", "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -648,9 +648,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.1" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "gl_generator" @@ -852,9 +852,9 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" +checksum = "cfa919a82ea574332e2de6e74b4c36e74d41982b335080fa59d4ef31be20fdf3" dependencies = [ "libc", "windows-sys 0.45.0", @@ -862,9 +862,9 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", @@ -1055,9 +1055,9 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memmap2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" dependencies = [ "libc", ] @@ -1073,9 +1073,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" dependencies = [ "autocfg", ] @@ -1215,15 +1215,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "nom8" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" -dependencies = [ - "memchr", -] - [[package]] name = "num-integer" version = "0.1.45" @@ -1266,18 +1257,18 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d829733185c1ca374f17e52b762f24f535ec625d2cc1f070e34c8a9068f341b" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2be1598bf1c313dcdd12092e3f1920f463462525a21b7b4e11b4168353d0123e" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -1403,12 +1394,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro-crate" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66618389e4ec1c7afe67d51a9bf34ff9236480f8d51e7489b7d5ab0303c13f34" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ "once_cell", - "toml_edit 0.18.1", + "toml_edit", ] [[package]] @@ -1498,9 +1489,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" dependencies = [ "either", "rayon-core", @@ -1508,9 +1499,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.10.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" dependencies = [ "crossbeam-channel", "crossbeam-deque", @@ -1552,9 +1543,9 @@ checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "rustix" -version = "0.36.8" +version = "0.36.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" dependencies = [ "bitflags", "errno", @@ -1566,9 +1557,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.11" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "rusty-xinput" @@ -1677,7 +1668,7 @@ dependencies = [ [[package]] name = "shipyard" version = "0.6.0" -source = "git+https://github.com/leudz/shipyard?rev=e30dece#e30dece960c9bd296c659f66215559cb5ccf4351" +source = "git+https://github.com/leudz/shipyard?rev=eb189f66#eb189f66ed2917440af3225d03b1feecb0d18bfd" dependencies = [ "hashbrown 0.12.3", "lock_api", @@ -1688,7 +1679,7 @@ dependencies = [ [[package]] name = "shipyard_proc" version = "0.3.0" -source = "git+https://github.com/leudz/shipyard?rev=e30dece#e30dece960c9bd296c659f66215559cb5ccf4351" +source = "git+https://github.com/leudz/shipyard?rev=eb189f66#eb189f66ed2917440af3225d03b1feecb0d18bfd" dependencies = [ "proc-macro2", "quote", @@ -1768,9 +1759,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.107" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", @@ -1794,18 +1785,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "a5ab016db510546d856297882807df8da66a16fb8c4101cb8b30054b0d5b2d9c" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.38" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e" dependencies = [ "proc-macro2", "quote", @@ -1845,16 +1836,10 @@ checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6" dependencies = [ "serde", "serde_spanned", - "toml_datetime 0.6.1", - "toml_edit 0.19.3", + "toml_datetime", + "toml_edit", ] -[[package]] -name = "toml_datetime" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" - [[package]] name = "toml_datetime" version = "0.6.1" @@ -1866,33 +1851,22 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.18.1" +version = "0.19.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" +checksum = "9a1eb0622d28f4b9c90adc4ea4b2b46b47663fde9ac5fafcb14a1369d5508825" dependencies = [ "indexmap", - "nom8", - "toml_datetime 0.5.1", -] - -[[package]] -name = "toml_edit" -version = "0.19.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6a7712b49e1775fb9a7b998de6635b299237f48b404dde71704f2e0e7f37e5" -dependencies = [ - "indexmap", - "nom8", "serde", "serde_spanned", - "toml_datetime 0.6.1", + "toml_datetime", + "winnow", ] [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "uuid" @@ -2244,6 +2218,15 @@ dependencies = [ "x11-dl", ] +[[package]] +name = "winnow" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee7b2c67f962bf5042bfd8b6a916178df33a26eec343ae064cb8e069f638fa6f" +dependencies = [ + "memchr", +] + [[package]] name = "wio" version = "0.2.2" diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 064d000..66f0eee 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -9,7 +9,7 @@ kubi-shared = { path = "../kubi-shared" } kubi-udp = { path = "../kubi-udp" } kubi-logging = { path = "../kubi-logging" } log = "*" -shipyard = { git = "https://github.com/leudz/shipyard", rev = "e30dece" } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66" } serde = "1.0" toml = "0.7" glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index b16a3b3..85d647e 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] glam = { version = "0.22", features = ["debug-glam-assert", "fast-math", "serde"] } -shipyard = { git = "https://github.com/leudz/shipyard", rev = "e30dece" } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66" } strum = { version = "0.24", features = ["derive"] } bincode = "2.0.0-rc" anyhow = "1.0" diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 78a8b35..09a7b02 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -15,7 +15,7 @@ image = { version = "0.24", default_features = false, features = ["png"] } strum = { version = "0.24", features = ["derive"] } hashbrown = "0.13" rayon = "1.6" -shipyard = { git = "https://github.com/leudz/shipyard", rev = "e30dece", features = ["thread_local"] } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66", features = ["thread_local"] } nohash-hasher = "0.2.0" anyhow = "1.0" flume = "0.10" From 95e3de7228263b3d59f0c7251db2017358a99ac8 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 00:46:12 +0100 Subject: [PATCH 138/160] create vscode settings.json --- .vscode/settings.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4fb2774 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "editor.tabSize": 2, + "rust-analyzer.diagnostics.disabled": [ + "unresolved-method" //rust-analyzer issue #14269 + ] +} From 6933987d7ba959ce20b16b02316fe57c564d840d Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 00:52:00 +0100 Subject: [PATCH 139/160] update glam to `0.23` --- Cargo.lock | 4 ++-- kubi-server/Cargo.toml | 2 +- kubi-shared/Cargo.toml | 2 +- kubi/Cargo.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4024f65..ce9e901 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -665,9 +665,9 @@ dependencies = [ [[package]] name = "glam" -version = "0.22.0" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f597d56c1bd55a811a1be189459e8fad2bbc272616375602443bdfb37fa774" +checksum = "8e4afd9ad95555081e109fe1d21f2a30c691b5f0919c67dfa690a2e1eb6bd51c" dependencies = [ "serde", ] diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 66f0eee..9e406c1 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -12,7 +12,7 @@ log = "*" shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66" } serde = "1.0" toml = "0.7" -glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } +glam = { version = "0.23", features = ["debug-glam-assert", "fast-math"] } hashbrown = "0.13" nohash-hasher = "0.2.0" anyhow = "1.0" diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 85d647e..7a4f1cc 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -7,7 +7,7 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -glam = { version = "0.22", features = ["debug-glam-assert", "fast-math", "serde"] } +glam = { version = "0.23", features = ["debug-glam-assert", "fast-math", "serde"] } shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66" } strum = { version = "0.24", features = ["derive"] } bincode = "2.0.0-rc" diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 09a7b02..6b16766 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -10,7 +10,7 @@ kubi-udp = { path = "../kubi-udp" } kubi-logging = { path = "../kubi-logging" } log = "*" glium = "0.32" -glam = { version = "0.22", features = ["debug-glam-assert", "fast-math"] } +glam = { version = "0.23", features = ["debug-glam-assert", "fast-math"] } image = { version = "0.24", default_features = false, features = ["png"] } strum = { version = "0.24", features = ["derive"] } hashbrown = "0.13" From 71823c7adad7fe67ef9bec1b3bce82f61066dd65 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 01:51:19 +0100 Subject: [PATCH 140/160] wtf --- kubi-server/src/auth.rs | 6 ++- kubi-server/src/chunk.rs | 4 +- kubi-shared/src/networking/state.rs | 3 +- kubi/src/camera/matrices.rs | 1 - kubi/src/networking.rs | 72 +++++++++++++++++++++++++---- kubi/src/world.rs | 3 -- kubi/src/world/loading.rs | 2 +- 7 files changed, 71 insertions(+), 20 deletions(-) diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs index 5a376a0..7ecaba0 100644 --- a/kubi-server/src/auth.rs +++ b/kubi-server/src/auth.rs @@ -16,6 +16,8 @@ pub fn authenticate_players( password } } = event { + log::info!("ClientHello from {} with username {} and password {:?}", from, username, password); + // Handle password auth if let Some(server_password) = &config.server.password { if let Some(user_password) = &password { @@ -34,12 +36,12 @@ pub fn authenticate_players( } //Spawn the user - // TODO + //TODO Spawn the user on server side //Approve the user server.0.send_message(*from, ServerToClientMessage::ServerHello { init: InitData { - users: todo!() + users: vec![] //TODO create init data } }).map_err(log_error).ok(); } diff --git a/kubi-server/src/chunk.rs b/kubi-server/src/chunk.rs index 26210cd..c214e43 100644 --- a/kubi-server/src/chunk.rs +++ b/kubi-server/src/chunk.rs @@ -1,9 +1,9 @@ +//TODO server-side chunk manager + pub struct Chunk { - //TODO } pub struct ChunkManager { - //TODO } pub fn server_chunk_response( diff --git a/kubi-shared/src/networking/state.rs b/kubi-shared/src/networking/state.rs index dd9a8b5..98492c3 100644 --- a/kubi-shared/src/networking/state.rs +++ b/kubi-shared/src/networking/state.rs @@ -1,7 +1,8 @@ use shipyard::{Unique, Component}; // disconnected => connect => join => load => ingame -#[derive(Unique, Component, PartialEq, Eq, Clone, Copy)] +#[derive(Unique, Component, PartialEq, Eq, Clone, Copy, Debug)] +#[repr(u8)] pub enum ClientJoinState { /// Not connected yet Disconnected, diff --git a/kubi/src/camera/matrices.rs b/kubi/src/camera/matrices.rs index 5f2c003..109c3de 100644 --- a/kubi/src/camera/matrices.rs +++ b/kubi/src/camera/matrices.rs @@ -20,7 +20,6 @@ fn update_perspective_matrix( mut vm_camera: ViewMut, resize: View, ) { - //TODO update on launch let Some(&size) = resize.iter().next() else { return }; diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 8c50747..7a763a4 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -1,4 +1,4 @@ -use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator, View, IntoIter}; +use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator, View, IntoIter, WorkloadModificator}; use glium::glutin::event_loop::ControlFlow; use std::net::SocketAddr; use kubi_udp::client::{Client, ClientConfig, ClientEvent}; @@ -6,7 +6,6 @@ use kubi_shared::networking::{ messages::{ClientToServerMessage, ServerToClientMessage}, state::ClientJoinState }; - use crate::{events::EventComponent, control_flow::SetControlFlow}; #[derive(Unique, Clone, Copy, PartialEq, Eq)] @@ -36,15 +35,17 @@ fn create_client( storages.add_unique(ClientJoinState::Disconnected); } -fn connect_client_if_needed( +fn connect_client( mut client: UniqueViewMut ) { - //NOTE: this used to be a condition function - //but that caused some issues for no reason - if client.0.has_not_made_connection_attempts() { - log::info!("Connect called"); - client.0.connect().unwrap(); - } + log::info!("Connect called"); + client.0.connect().unwrap(); +} + +fn should_connect( + client: UniqueView +) -> bool { + client.0.has_not_made_connection_attempts() } fn update_client( @@ -67,12 +68,49 @@ fn insert_client_events( })); } +fn set_client_join_state_to_connected( + mut join_state: UniqueViewMut +) { + log::info!("Setting ClientJoinState"); + *join_state = ClientJoinState::Connected; +} + +fn say_hello( + client: UniqueViewMut, +) { + log::info!("Authenticating"); + client.0.send_message(ClientToServerMessage::ClientHello { + username: "Sbeve".into(), + password: None + }).unwrap(); +} + +fn check_server_hello_response( + network_events: View, + mut join_state: UniqueViewMut +) { + for event in network_events.iter() { + if let ClientEvent::MessageReceived(ServerToClientMessage::ServerHello { init }) = &event.0 { + log::info!("Joined the server!"); + //TODO handle init data + *join_state = ClientJoinState::Joined; + } + } +} + pub fn update_networking() -> Workload { ( create_client.run_if_missing_unique::(), - connect_client_if_needed, + connect_client.run_if(should_connect), update_client, insert_client_events, + ( + set_client_join_state_to_connected, + say_hello, + ).into_workload().run_if(if_just_connected), + ( + check_server_hello_response, + ).into_workload().run_if(is_join_state::<{ClientJoinState::Connected as u8}>) ).into_workload() } @@ -90,6 +128,20 @@ pub fn disconnect_on_exit( } } +// conditions + +fn if_just_connected( + network_events: View, +) -> bool { + network_events.iter().any(|event| matches!(event.0, ClientEvent::Connected(_))) +} + +fn is_join_state( + join_state: UniqueView +) -> bool { + (*join_state as u8) == STATE +} + pub fn is_multiplayer( game_type: UniqueView ) -> bool { diff --git a/kubi/src/world.rs b/kubi/src/world.rs index 03d91c2..50664d2 100644 --- a/kubi/src/world.rs +++ b/kubi/src/world.rs @@ -18,9 +18,6 @@ use chunk::{Chunk, ChunkMesh, CHUNK_SIZE}; use tasks::ChunkTaskManager; use queue::BlockUpdateQueue; -//TODO separate world struct for render data -// because this is not send-sync - #[derive(Default, Unique)] pub struct ChunkStorage { pub chunks: HashMap diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index 0b7338c..ec5e7ca 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -34,7 +34,7 @@ pub fn update_chunks_if_player_moved( mut vm_world: UniqueViewMut, ) { //Check if the player actually moved - //TODO fix this also triggers on rotation, only activate when the player crosses the chnk border + //TODO fix this also triggers on rotation, only activate when the player crosses the chunk border let Some((_, transform)) = (&v_local_player, v_transform.inserted_or_modified()).iter().next() else { return }; From 16e7b7e58837697f40d63ab1c64f96fa59319930 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 01:59:54 +0100 Subject: [PATCH 141/160] Make the outer system seq --- kubi/src/networking.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 7a763a4..7d72c8b 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -111,7 +111,7 @@ pub fn update_networking() -> Workload { ( check_server_hello_response, ).into_workload().run_if(is_join_state::<{ClientJoinState::Connected as u8}>) - ).into_workload() + ).into_sequential_workload() //Fixes } pub fn disconnect_on_exit( @@ -133,7 +133,7 @@ pub fn disconnect_on_exit( fn if_just_connected( network_events: View, ) -> bool { - network_events.iter().any(|event| matches!(event.0, ClientEvent::Connected(_))) + network_events.iter().any(|event| matches!(&event.0, ClientEvent::Connected(_))) } fn is_join_state( From 12fee770872839aa4cb7512cd052595945c6d248 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 02:28:16 +0100 Subject: [PATCH 142/160] change comment --- kubi/src/networking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 7d72c8b..6630c1c 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -111,7 +111,7 @@ pub fn update_networking() -> Workload { ( check_server_hello_response, ).into_workload().run_if(is_join_state::<{ClientJoinState::Connected as u8}>) - ).into_sequential_workload() //Fixes + ).into_sequential_workload() //HACK Weird issues with shipyard removed } pub fn disconnect_on_exit( From a46c5baab84292aaecb76d4a5b435816e07034e8 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 03:05:02 +0100 Subject: [PATCH 143/160] basic netw --- kubi-server/src/chunk.rs | 8 +++++++- kubi/src/world/loading.rs | 19 ++++++++++++++----- kubi/src/world/tasks.rs | 18 ------------------ 3 files changed, 21 insertions(+), 24 deletions(-) diff --git a/kubi-server/src/chunk.rs b/kubi-server/src/chunk.rs index c214e43..2396e84 100644 --- a/kubi-server/src/chunk.rs +++ b/kubi-server/src/chunk.rs @@ -1,9 +1,15 @@ -//TODO server-side chunk manager +use glam::IVec3; +use hashbrown::HashMap; +use kubi_shared::chunk::BlockData; +use shipyard::Unique; pub struct Chunk { + pub blocks: BlockData } +#[derive(Unique)] pub struct ChunkManager { + pub chunks: HashMap } pub fn server_chunk_response( diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index ec5e7ca..e16a72f 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -1,12 +1,14 @@ use glam::{IVec3, ivec3}; use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType}; +use kubi_shared::networking::messages::ClientToServerMessage; use shipyard::{View, UniqueView, UniqueViewMut, IntoIter, Workload, IntoWorkload, NonSendSync, track}; use crate::{ player::MainPlayer, transform::Transform, settings::GameSettings, rendering::Renderer, - state::GameState + state::GameState, + networking::UdpClient, }; use super::{ ChunkStorage, ChunkMeshStorage, @@ -118,6 +120,7 @@ fn unload_downgrade_chunks( fn start_required_tasks( task_manager: UniqueView, + udp_client: Option>, mut world: UniqueViewMut, ) { if !world.is_modified() { @@ -130,10 +133,16 @@ fn start_required_tasks( match chunk.desired_state { DesiredChunkState::Loaded | DesiredChunkState::Rendered if chunk.current_state == CurrentChunkState::Nothing => { //start load task - task_manager.spawn_task(ChunkTask::LoadChunk { - seed: 0xbeef_face_dead_cafe, - position - }); + if let Some(client) = &udp_client { + client.0.send_message(ClientToServerMessage::ChunkRequest { + chunk: position.to_array() + }).unwrap(); + } else { + task_manager.spawn_task(ChunkTask::LoadChunk { + seed: 0xbeef_face_dead_cafe, + position + }); + } //Update chunk state let chunk = world.chunks.get_mut(&position).unwrap(); chunk.current_state = CurrentChunkState::Loading; diff --git a/kubi/src/world/tasks.rs b/kubi/src/world/tasks.rs index 60b39e0..705b9a5 100644 --- a/kubi/src/world/tasks.rs +++ b/kubi/src/world/tasks.rs @@ -77,24 +77,6 @@ impl ChunkTaskManager { } } -pub fn spawn_task_or_get_from_network_if_possible(client: Option<&mut UdpClient>, manager: &mut ChunkTaskManager, task: ChunkTask) { - match &task { - ChunkTask::LoadChunk { seed, position } => { - match client { - Some(client) => { - client.0.send_message(ClientToServerMessage::ChunkRequest { chunk: position.to_array() }).unwrap(); - }, - None => { - manager.spawn_task(task) - } - } - }, - _ => { - manager.spawn_task(task) - } - } -} - //TODO get rid of this, this is awfulll pub fn inject_network_responses_into_manager_queue( manager: UniqueView, From 639685e76b5b5742ccb45a43cc63ba78e69eef34 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 04:50:06 +0100 Subject: [PATCH 144/160] server --- Cargo.lock | 2 + Server.toml | 3 + kubi-server/Cargo.toml | 2 + kubi-server/src/chunk.rs | 19 ----- kubi-server/src/config.rs | 8 +- kubi-server/src/main.rs | 6 +- kubi-server/src/world.rs | 111 +++++++++++++++++++++++++ kubi-server/src/world/chunk.rs | 29 +++++++ kubi-server/src/world/tasks.rs | 58 +++++++++++++ kubi-shared/src/networking/messages.rs | 8 +- kubi/src/world/loading.rs | 2 +- kubi/src/world/tasks.rs | 7 +- 12 files changed, 226 insertions(+), 29 deletions(-) delete mode 100644 kubi-server/src/chunk.rs create mode 100644 kubi-server/src/world.rs create mode 100644 kubi-server/src/world/chunk.rs create mode 100644 kubi-server/src/world/tasks.rs diff --git a/Cargo.lock b/Cargo.lock index ce9e901..8245711 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -928,6 +928,7 @@ name = "kubi-server" version = "0.1.0" dependencies = [ "anyhow", + "flume", "glam", "hashbrown 0.13.2", "kubi-logging", @@ -935,6 +936,7 @@ dependencies = [ "kubi-udp", "log", "nohash-hasher", + "rayon", "serde", "shipyard", "toml", diff --git a/Server.toml b/Server.toml index 14ae320..69c01e8 100644 --- a/Server.toml +++ b/Server.toml @@ -2,3 +2,6 @@ address = "0.0.0.0:12345" max_clients = 254 timeout_ms = 10000 + +[world] +seed = 0xbeef_face_dead_cafe diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 9e406c1..f3b9d0b 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -16,6 +16,8 @@ glam = { version = "0.23", features = ["debug-glam-assert", "fast-math"] } hashbrown = "0.13" nohash-hasher = "0.2.0" anyhow = "1.0" +rayon = "1.6" +flume = "0.10" [features] default = [] diff --git a/kubi-server/src/chunk.rs b/kubi-server/src/chunk.rs deleted file mode 100644 index 2396e84..0000000 --- a/kubi-server/src/chunk.rs +++ /dev/null @@ -1,19 +0,0 @@ -use glam::IVec3; -use hashbrown::HashMap; -use kubi_shared::chunk::BlockData; -use shipyard::Unique; - -pub struct Chunk { - pub blocks: BlockData -} - -#[derive(Unique)] -pub struct ChunkManager { - pub chunks: HashMap -} - -pub fn server_chunk_response( - -) { - -} diff --git a/kubi-server/src/config.rs b/kubi-server/src/config.rs index 2ae114f..3a6abf1 100644 --- a/kubi-server/src/config.rs +++ b/kubi-server/src/config.rs @@ -10,9 +10,15 @@ pub struct ConfigTableServer { pub password: Option, } +#[derive(Serialize, Deserialize)] +pub struct ConfigTableWorld { + pub seed: u64, +} + #[derive(Unique, Serialize, Deserialize)] pub struct ConfigTable { - pub server: ConfigTableServer + pub server: ConfigTableServer, + pub world: ConfigTableWorld, } pub fn read_config( diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index 926c6b5..fc24b57 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -1,4 +1,3 @@ - use shipyard::{World, Workload, IntoWorkload}; use std::{thread, time::Duration}; @@ -6,17 +5,19 @@ pub(crate) mod util; pub(crate) mod config; pub(crate) mod server; pub(crate) mod client; -pub(crate) mod chunk; +pub(crate) mod world; pub(crate) mod auth; use config::read_config; use server::{bind_server, update_server, update_server_events}; use auth::authenticate_players; +use world::{update_world, init_world}; fn initialize() -> Workload { ( read_config, bind_server, + init_world, ).into_workload() } @@ -25,6 +26,7 @@ fn update() -> Workload { update_server, update_server_events, authenticate_players, + update_world, ).into_workload() } diff --git a/kubi-server/src/world.rs b/kubi-server/src/world.rs new file mode 100644 index 0000000..b555576 --- /dev/null +++ b/kubi-server/src/world.rs @@ -0,0 +1,111 @@ +use shipyard::{Unique, UniqueView, UniqueViewMut, Workload, IntoWorkload, AllStoragesView}; +use glam::IVec3; +use hashbrown::HashMap; +use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; +use kubi_udp::server::ServerEvent; +use crate::{ + server::{UdpServer, ServerEvents}, + config::ConfigTable, + util::log_error, +}; + +pub mod chunk; +pub mod tasks; + +use chunk::Chunk; + +use self::{tasks::{ChunkTaskManager, ChunkTask, ChunkTaskResponse}, chunk::ChunkState}; + +#[derive(Unique, Default)] +pub struct ChunkManager { + pub chunks: HashMap +} +impl ChunkManager { + pub fn new() -> Self { + Self::default() + } +} + +fn process_chunk_requests( + mut server: UniqueViewMut, + events: UniqueView, + mut chunk_manager: UniqueViewMut, + task_manager: UniqueView, + config: UniqueView +) { + for event in &events.0 { + if let ServerEvent::MessageReceived { + from: client_id, + message: ClientToServerMessage::ChunkSubRequest { + chunk: chunk_position + } + } = event { + let chunk_position = IVec3::from_array(*chunk_position); + if let Some(chunk) = chunk_manager.chunks.get_mut(&chunk_position) { + chunk.subscriptions.insert(*client_id); + //TODO Start task here if status is "Nothing" + if let Some(blocks) = &chunk.blocks { + server.0.send_message(*client_id, kubi_shared::networking::messages::ServerToClientMessage::ChunkResponse { + chunk: chunk_position.to_array(), + data: blocks.clone(), + queued: Vec::with_capacity(0) + }).map_err(log_error).ok(); + } + } else { + let mut chunk = Chunk::new(chunk_position); + chunk.state = ChunkState::Loading; + chunk_manager.chunks.insert(chunk_position, chunk); + task_manager.spawn_task(ChunkTask::LoadChunk { + position: chunk_position, + seed: config.world.seed, + }); + } + } + } +} + +fn process_finished_tasks( + mut server: UniqueViewMut, + task_manager: UniqueView, + mut chunk_manager: UniqueViewMut, +) { + while let Some(res) = task_manager.receive() { + let ChunkTaskResponse::ChunkLoaded { chunk_position, blocks, queue } = res; + let Some(chunk) = chunk_manager.chunks.get_mut(&chunk_position) else { + log::warn!("Chunk discarded: Doesn't exist"); + continue + }; + if chunk.state != ChunkState::Loading { + log::warn!("Chunk discarded: Not Loading"); + continue + } + chunk.state = ChunkState::Loaded; + chunk.blocks = Some(blocks.clone()); + for &subscriber in &chunk.subscriptions { + server.0.send_message(subscriber, ServerToClientMessage::ChunkResponse { + chunk: chunk_position.to_array(), + data: blocks.clone(), + queued: queue.iter().map(|item| (item.position.to_array(), item.block_type)).collect() + }).map_err(log_error).ok(); + } + } +} + +fn init_chunk_manager( + storages: AllStoragesView +) { + storages.add_unique(ChunkManager::new()); +} + +pub fn init_world() -> Workload { + ( + init_chunk_manager + ).into_workload() +} + +pub fn update_world() -> Workload { + ( + process_chunk_requests, + process_finished_tasks, + ).into_workload() +} diff --git a/kubi-server/src/world/chunk.rs b/kubi-server/src/world/chunk.rs new file mode 100644 index 0000000..a83b0ee --- /dev/null +++ b/kubi-server/src/world/chunk.rs @@ -0,0 +1,29 @@ +use glam::IVec3; +use hashbrown::HashSet; +use nohash_hasher::BuildNoHashHasher; +use kubi_shared::chunk::BlockData; +use kubi_udp::{ClientId, ClientIdRepr}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum ChunkState { + Nothing, + Loading, + Loaded, +} + +pub struct Chunk { + pub position: IVec3, + pub state: ChunkState, + pub blocks: Option, + pub subscriptions: HashSet>, +} +impl Chunk { + pub fn new(position: IVec3) -> Self { + Self { + position, + state: ChunkState::Nothing, + blocks: None, + subscriptions: HashSet::with_hasher(BuildNoHashHasher::default()), + } + } +} diff --git a/kubi-server/src/world/tasks.rs b/kubi-server/src/world/tasks.rs new file mode 100644 index 0000000..fd2d120 --- /dev/null +++ b/kubi-server/src/world/tasks.rs @@ -0,0 +1,58 @@ +use shipyard::{Unique, AllStoragesView}; +use flume::{unbounded, Sender, Receiver}; +use glam::IVec3; +use rayon::{ThreadPool, ThreadPoolBuilder}; +use anyhow::Result; +use kubi_shared::{ + chunk::BlockData, + worldgen::{QueuedBlock, generate_world} +}; + +pub enum ChunkTask { + LoadChunk { + position: IVec3, + seed: u64, + } +} + +pub enum ChunkTaskResponse { + ChunkLoaded { + chunk_position: IVec3, + blocks: BlockData, + queue: Vec + } +} + +#[derive(Unique)] +pub struct ChunkTaskManager { + channel: (Sender, Receiver), + pool: ThreadPool, +} +impl ChunkTaskManager { + pub fn new() -> Result { + Ok(Self { + channel: unbounded(), + pool: ThreadPoolBuilder::new().build()? + }) + } + pub fn spawn_task(&self, task: ChunkTask) { + let sender = self.channel.0.clone(); + self.pool.spawn(move || { + sender.send(match task { + ChunkTask::LoadChunk { position: chunk_position, seed } => { + let (blocks, queue) = generate_world(chunk_position, seed); + ChunkTaskResponse::ChunkLoaded { chunk_position, blocks, queue } + } + }).unwrap() + }) + } + pub fn receive(&self) -> Option { + self.channel.1.try_recv().ok() + } +} + +pub fn init_chunk_task_manager( + storages: AllStoragesView +) { + storages.add_unique(ChunkTaskManager::new().expect("ChunkTaskManager Init failed")); +} diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index 0b553c6..c8b17a9 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -1,7 +1,6 @@ use std::num::NonZeroUsize; - use bincode::{Encode, Decode}; -use crate::chunk::BlockData; +use crate::{chunk::BlockData, block::Block}; type IVec3Arr = [i32; 3]; type Vec3Arr = [f32; 3]; @@ -20,7 +19,7 @@ pub enum ClientToServerMessage { velocity: Vec3Arr, direction: QuatArr, }, - ChunkRequest { + ChunkSubRequest { chunk: IVec3Arr, }, } @@ -54,6 +53,7 @@ pub enum ServerToClientMessage { }, ChunkResponse { chunk: IVec3Arr, - data: BlockData + data: BlockData, + queued: Vec<(IVec3Arr, Block)>, } } diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index e16a72f..76d67f3 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -134,7 +134,7 @@ fn start_required_tasks( DesiredChunkState::Loaded | DesiredChunkState::Rendered if chunk.current_state == CurrentChunkState::Nothing => { //start load task if let Some(client) = &udp_client { - client.0.send_message(ClientToServerMessage::ChunkRequest { + client.0.send_message(ClientToServerMessage::ChunkSubRequest { chunk: position.to_array() }).unwrap(); } else { diff --git a/kubi/src/world/tasks.rs b/kubi/src/world/tasks.rs index 705b9a5..5d855e1 100644 --- a/kubi/src/world/tasks.rs +++ b/kubi/src/world/tasks.rs @@ -83,12 +83,15 @@ pub fn inject_network_responses_into_manager_queue( events: View ) { for event in events.iter() { - if let ClientEvent::MessageReceived(ServerToClientMessage::ChunkResponse { chunk, data }) = &event.0 { + if let ClientEvent::MessageReceived(ServerToClientMessage::ChunkResponse { chunk, data, queued }) = &event.0 { let position = IVec3::from_array(*chunk); manager.add_sussy_response(ChunkTaskResponse::LoadedChunk { position, chunk_data: data.clone(), - queued: Vec::with_capacity(0) + queued: queued.iter().map(|&(position, block_type)| QueuedBlock { + position: IVec3::from_array(position), + block_type + }).collect() }); } } From f4bbfd3e8a09d0a32a16304641f42300ac8c6290 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 04:56:51 +0100 Subject: [PATCH 145/160] fix --- Server.toml | 2 +- kubi-server/src/world.rs | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Server.toml b/Server.toml index 69c01e8..1cfc2a3 100644 --- a/Server.toml +++ b/Server.toml @@ -4,4 +4,4 @@ max_clients = 254 timeout_ms = 10000 [world] -seed = 0xbeef_face_dead_cafe +seed = 0xfeb_face_dead_cafe diff --git a/kubi-server/src/world.rs b/kubi-server/src/world.rs index b555576..84c1561 100644 --- a/kubi-server/src/world.rs +++ b/kubi-server/src/world.rs @@ -14,7 +14,7 @@ pub mod tasks; use chunk::Chunk; -use self::{tasks::{ChunkTaskManager, ChunkTask, ChunkTaskResponse}, chunk::ChunkState}; +use self::{tasks::{ChunkTaskManager, ChunkTask, ChunkTaskResponse, init_chunk_task_manager}, chunk::ChunkState}; #[derive(Unique, Default)] pub struct ChunkManager { @@ -99,7 +99,8 @@ fn init_chunk_manager( pub fn init_world() -> Workload { ( - init_chunk_manager + init_chunk_manager, + init_chunk_task_manager, ).into_workload() } From a4705433253bdc6292a0fda996015916db87edba Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 17:05:55 +0100 Subject: [PATCH 146/160] wip server chunks --- kubi-server/src/world.rs | 2 ++ kubi-udp/tests/test.rs | 2 +- kubi/src/loading_screen.rs | 15 ++++++++++++++- kubi/src/main.rs | 2 +- kubi/src/world/tasks.rs | 4 ++-- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/kubi-server/src/world.rs b/kubi-server/src/world.rs index 84c1561..29006c3 100644 --- a/kubi-server/src/world.rs +++ b/kubi-server/src/world.rs @@ -54,6 +54,7 @@ fn process_chunk_requests( } else { let mut chunk = Chunk::new(chunk_position); chunk.state = ChunkState::Loading; + chunk.subscriptions.insert(*client_id); chunk_manager.chunks.insert(chunk_position, chunk); task_manager.spawn_task(ChunkTask::LoadChunk { position: chunk_position, @@ -88,6 +89,7 @@ fn process_finished_tasks( queued: queue.iter().map(|item| (item.position.to_array(), item.block_type)).collect() }).map_err(log_error).ok(); } + log::debug!("Chunk {chunk_position} loaded, {} subs", chunk.subscriptions.len()) } } diff --git a/kubi-udp/tests/test.rs b/kubi-udp/tests/test.rs index 6de54d2..7deb52c 100644 --- a/kubi-udp/tests/test.rs +++ b/kubi-udp/tests/test.rs @@ -80,7 +80,7 @@ fn test_connection() { log::info!("client received message"); assert_eq!(data, STC_MSG, "Received message not equal"); message_received = true; - client.disconnect(); + client.disconnect().unwrap(); }, _ => () } diff --git a/kubi/src/loading_screen.rs b/kubi/src/loading_screen.rs index cb01e21..550a7db 100644 --- a/kubi/src/loading_screen.rs +++ b/kubi/src/loading_screen.rs @@ -1,4 +1,5 @@ use shipyard::{UniqueView, UniqueViewMut, Workload, IntoWorkload, EntityId, Unique, AllStoragesViewMut, ViewMut, Get, SystemModificator, track}; +use glium::glutin::event::VirtualKeyCode; use glam::{Mat3, vec2}; use crate::{ world::ChunkStorage, @@ -7,7 +8,9 @@ use crate::{ gui::{ GuiComponent, progressbar::ProgressbarComponent - }, rendering::{WindowSize, if_resized}, + }, + rendering::{WindowSize, if_resized}, + input::RawKbmInputState, }; #[derive(Unique, Clone, Copy)] @@ -69,6 +72,15 @@ fn switch_to_ingame_if_loaded( } } +fn override_loading( + kbm_state: UniqueView, + mut state: UniqueViewMut +) { + if kbm_state.keyboard_state.contains(&VirtualKeyCode::F) { + state.0 = Some(GameState::InGame); + } +} + fn despawn_loading_screen_if_switching_state( mut storages: AllStoragesViewMut, ) { @@ -85,6 +97,7 @@ pub fn update_loading_screen() -> Workload { spawn_loading_screen.run_if_missing_unique::(), resize_progress_bar.run_if(if_resized), update_progress_bar_progress, + override_loading, switch_to_ingame_if_loaded, despawn_loading_screen_if_switching_state.run_if(is_changing_state), ).into_workload() diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 472d3c0..76481e5 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -110,7 +110,7 @@ fn update() -> Workload { ( update_networking, inject_network_responses_into_manager_queue, - ).into_workload().run_if(is_multiplayer), + ).into_sequential_workload().run_if(is_multiplayer), ( switch_to_loading_if_connected ).into_workload().run_if(is_connecting), diff --git a/kubi/src/world/tasks.rs b/kubi/src/world/tasks.rs index 5d855e1..0bc05ad 100644 --- a/kubi/src/world/tasks.rs +++ b/kubi/src/world/tasks.rs @@ -1,7 +1,7 @@ use flume::{Sender, Receiver}; use glam::IVec3; use kubi_shared::{ - networking::messages::{ClientToServerMessage, ServerToClientMessage}, + networking::messages::ServerToClientMessage, worldgen::QueuedBlock }; use shipyard::{Unique, UniqueView, View, IntoIter}; @@ -13,7 +13,7 @@ use super::{ }; use crate::{ rendering::world::ChunkVertex, - networking::{UdpClient, NetworkEvent} + networking::NetworkEvent, }; use kubi_udp::client::ClientEvent; From ce454f061103fb16eb169579bf99158662b1fdc4 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 21:18:59 +0100 Subject: [PATCH 147/160] make packet size a const --- kubi-udp/src/client.rs | 4 ++-- kubi-udp/src/common.rs | 3 +++ kubi-udp/src/server.rs | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs index 49cdde8..1431542 100644 --- a/kubi-udp/src/client.rs +++ b/kubi-udp/src/client.rs @@ -9,7 +9,7 @@ use std::{ use crate::{ BINCODE_CONFIG, packet::{ClientPacket, IdClientPacket, IdServerPacket, ServerPacket, Message}, - common::{ClientId, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID} + common::{ClientId, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID, PACKET_SIZE} }; #[derive(Default, Clone, Debug)] @@ -201,7 +201,7 @@ impl Client where S: Message, R: Message { self.last_heartbeat = Instant::now(); } //receive - let mut buf = [0; u16::MAX as usize]; + let mut buf = [0; PACKET_SIZE]; loop { match self.socket.recv(&mut buf) { Ok(length) => { diff --git a/kubi-udp/src/common.rs b/kubi-udp/src/common.rs index bb74b63..be598a7 100644 --- a/kubi-udp/src/common.rs +++ b/kubi-udp/src/common.rs @@ -2,7 +2,10 @@ use std::num::NonZeroU8; pub type ClientId = NonZeroU8; pub type ClientIdRepr = u8; + pub const MAX_CLIENTS: usize = u8::MAX as _; pub const PROTOCOL_ID: u16 = 1; pub const DEFAULT_USER_PROTOCOL_ID: u16 = 0xffff; + +pub const PACKET_SIZE: usize = u16::MAX as usize; diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs index ad1074c..337f292 100644 --- a/kubi-udp/src/server.rs +++ b/kubi-udp/src/server.rs @@ -10,7 +10,7 @@ use hashbrown::HashMap; use nohash_hasher::BuildNoHashHasher; use crate::{ BINCODE_CONFIG, - common::{ClientId, ClientIdRepr, MAX_CLIENTS, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID}, + common::{ClientId, ClientIdRepr, MAX_CLIENTS, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID, PACKET_SIZE}, packet::{IdClientPacket, ClientPacket, ServerPacket, IdServerPacket, Message} }; @@ -177,7 +177,7 @@ impl Server where S: Message, R: Message { true }); - let mut buf = [0; u16::MAX as usize]; + let mut buf = [0; PACKET_SIZE]; loop { match self.socket.recv_from(&mut buf) { Ok((len, addr)) => { From d7c3b6f6ba3d34fcf74b4db300288c3208c9d851 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 21:29:05 +0100 Subject: [PATCH 148/160] ew --- kubi-server/src/world.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kubi-server/src/world.rs b/kubi-server/src/world.rs index 29006c3..36f7070 100644 --- a/kubi-server/src/world.rs +++ b/kubi-server/src/world.rs @@ -70,6 +70,7 @@ fn process_finished_tasks( task_manager: UniqueView, mut chunk_manager: UniqueViewMut, ) { + let mut limit: usize = 8; while let Some(res) = task_manager.receive() { let ChunkTaskResponse::ChunkLoaded { chunk_position, blocks, queue } = res; let Some(chunk) = chunk_manager.chunks.get_mut(&chunk_position) else { @@ -89,7 +90,12 @@ fn process_finished_tasks( queued: queue.iter().map(|item| (item.position.to_array(), item.block_type)).collect() }).map_err(log_error).ok(); } - log::debug!("Chunk {chunk_position} loaded, {} subs", chunk.subscriptions.len()) + log::debug!("Chunk {chunk_position} loaded, {} subs", chunk.subscriptions.len()); + //HACK: Implement proper flow control/reliable transport in kubi-udp + limit -= 1; + if limit == 0 { + break; + } } } From 39d4fd129ab86d397f1e02d9a78a1d1f54f898ca Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Tue, 7 Mar 2023 23:36:04 +0100 Subject: [PATCH 149/160] Remove kubi-udp --- Cargo.lock | 14 -- Cargo.toml | 2 +- kubi-server/Cargo.toml | 1 - kubi-server/src/auth.rs | 1 - kubi-server/src/client.rs | 1 - kubi-server/src/world.rs | 1 - kubi-server/src/world/chunk.rs | 1 - kubi-udp/Cargo.toml | 17 --- kubi-udp/src/client.rs | 270 --------------------------------- kubi-udp/src/common.rs | 11 -- kubi-udp/src/lib.rs | 13 -- kubi-udp/src/packet.rs | 33 ---- kubi-udp/src/server.rs | 266 -------------------------------- kubi-udp/tests/test.rs | 93 ------------ kubi/Cargo.toml | 1 - kubi/src/networking.rs | 1 - kubi/src/world/tasks.rs | 1 - 17 files changed, 1 insertion(+), 726 deletions(-) delete mode 100644 kubi-udp/Cargo.toml delete mode 100644 kubi-udp/src/client.rs delete mode 100644 kubi-udp/src/common.rs delete mode 100644 kubi-udp/src/lib.rs delete mode 100644 kubi-udp/src/packet.rs delete mode 100644 kubi-udp/src/server.rs delete mode 100644 kubi-udp/tests/test.rs diff --git a/Cargo.lock b/Cargo.lock index 8245711..b2c5b20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -906,7 +906,6 @@ dependencies = [ "image", "kubi-logging", "kubi-shared", - "kubi-udp", "log", "nohash-hasher", "rayon", @@ -933,7 +932,6 @@ dependencies = [ "hashbrown 0.13.2", "kubi-logging", "kubi-shared", - "kubi-udp", "log", "nohash-hasher", "rayon", @@ -956,18 +954,6 @@ dependencies = [ "strum", ] -[[package]] -name = "kubi-udp" -version = "0.1.0" -dependencies = [ - "anyhow", - "bincode", - "hashbrown 0.13.2", - "kubi-logging", - "log", - "nohash-hasher", -] - [[package]] name = "lazy_static" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index ae1d7de..cfbd2e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["kubi", "kubi-server", "kubi-shared", "kubi-udp", "kubi-logging"] +members = ["kubi", "kubi-server", "kubi-shared", "kubi-logging"] resolver = "2" [profile.release-with-debug] diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index f3b9d0b..3784589 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -6,7 +6,6 @@ publish = false [dependencies] kubi-shared = { path = "../kubi-shared" } -kubi-udp = { path = "../kubi-udp" } kubi-logging = { path = "../kubi-logging" } log = "*" shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66" } diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs index 7ecaba0..3f10a61 100644 --- a/kubi-server/src/auth.rs +++ b/kubi-server/src/auth.rs @@ -1,6 +1,5 @@ use shipyard::{UniqueView, UniqueViewMut}; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage, InitData}; -use kubi_udp::server::ServerEvent; use crate::{server::{ServerEvents, UdpServer}, config::ConfigTable, util::log_error}; pub fn authenticate_players( diff --git a/kubi-server/src/client.rs b/kubi-server/src/client.rs index 23587b7..41423ba 100644 --- a/kubi-server/src/client.rs +++ b/kubi-server/src/client.rs @@ -1,7 +1,6 @@ use shipyard::{Component, EntityId}; use hashbrown::HashMap; use nohash_hasher::BuildNoHashHasher; -use kubi_udp::{ClientId, ClientIdRepr}; #[derive(Component)] pub struct Client(ClientId); diff --git a/kubi-server/src/world.rs b/kubi-server/src/world.rs index 36f7070..c7de485 100644 --- a/kubi-server/src/world.rs +++ b/kubi-server/src/world.rs @@ -2,7 +2,6 @@ use shipyard::{Unique, UniqueView, UniqueViewMut, Workload, IntoWorkload, AllSto use glam::IVec3; use hashbrown::HashMap; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; -use kubi_udp::server::ServerEvent; use crate::{ server::{UdpServer, ServerEvents}, config::ConfigTable, diff --git a/kubi-server/src/world/chunk.rs b/kubi-server/src/world/chunk.rs index a83b0ee..8a26922 100644 --- a/kubi-server/src/world/chunk.rs +++ b/kubi-server/src/world/chunk.rs @@ -2,7 +2,6 @@ use glam::IVec3; use hashbrown::HashSet; use nohash_hasher::BuildNoHashHasher; use kubi_shared::chunk::BlockData; -use kubi_udp::{ClientId, ClientIdRepr}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ChunkState { diff --git a/kubi-udp/Cargo.toml b/kubi-udp/Cargo.toml deleted file mode 100644 index 605363e..0000000 --- a/kubi-udp/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "kubi-udp" -version = "0.1.0" -edition = "2021" -publish = false - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bincode = "2.0.0-rc" -anyhow = "1.0" -hashbrown = "0.13" -nohash-hasher = "0.2.0" -log = "0.4" - -[dev-dependencies] -kubi-logging = { path = "../kubi-logging" } diff --git a/kubi-udp/src/client.rs b/kubi-udp/src/client.rs deleted file mode 100644 index 1431542..0000000 --- a/kubi-udp/src/client.rs +++ /dev/null @@ -1,270 +0,0 @@ -use anyhow::{Result, bail}; -use std::{ - net::{UdpSocket, SocketAddr}, - time::{Instant, Duration}, - marker::PhantomData, - collections::{VecDeque, vec_deque::Drain as DrainDeque}, - io::ErrorKind, -}; -use crate::{ - BINCODE_CONFIG, - packet::{ClientPacket, IdClientPacket, IdServerPacket, ServerPacket, Message}, - common::{ClientId, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID, PACKET_SIZE} -}; - -#[derive(Default, Clone, Debug)] -#[repr(u8)] -pub enum DisconnectReason { - #[default] - NotConnected, - ClientDisconnected, - KickedByServer(Option), - Timeout, - ConnectionReset, - InvalidProtocolId, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum ClientStatus { - Disconnected, - Connecting, - Connected, -} - -#[derive(Clone, Copy, Debug)] -pub struct ClientConfig { - pub protocol_id: u16, - pub timeout: Duration, - pub heartbeat_interval: Duration, -} -impl Default for ClientConfig { - fn default() -> Self { - Self { - protocol_id: DEFAULT_USER_PROTOCOL_ID, - timeout: Duration::from_secs(5), - heartbeat_interval: Duration::from_secs(3), - } - } -} - -pub enum ClientEvent where T: Message { - Connected(ClientId), - Disconnected(DisconnectReason), - MessageReceived(T) -} - -pub struct Client where S: Message, R: Message { - config: ClientConfig, - addr: SocketAddr, - socket: UdpSocket, - status: ClientStatus, - timeout: Instant, - last_heartbeat: Instant, - client_id: Option, - disconnect_reason: DisconnectReason, - event_queue: VecDeque>, - _s: PhantomData, -} -impl Client where S: Message, R: Message { - #[inline] - pub fn new(addr: SocketAddr, config: ClientConfig) -> Result { - if config.protocol_id == 0 { - log::warn!("Warning: using 0 as protocol_id is not recommended"); - } - if config.protocol_id == DEFAULT_USER_PROTOCOL_ID { - log::warn!("Warning: using default protocol_id is not recommended"); - } - let bind_addr: SocketAddr = "0.0.0.0:0".parse().unwrap(); - let socket = UdpSocket::bind(bind_addr)?; - socket.set_nonblocking(true)?; - Ok(Self { - addr, - config, - socket, - status: ClientStatus::Disconnected, - timeout: Instant::now(), - last_heartbeat: Instant::now(), - client_id: None, - disconnect_reason: DisconnectReason::default(), - event_queue: VecDeque::new(), - _s: PhantomData, - }) - } - - fn send_raw_packet(&self, packet: ClientPacket) -> Result<()> { - let id_packet = IdClientPacket(self.client_id, packet); - let bytes = bincode::encode_to_vec(id_packet, BINCODE_CONFIG)?; - self.socket.send(&bytes)?; - Ok(()) - } - - fn disconnect_inner(&mut self, reason: DisconnectReason, silent: bool) -> Result<()> { - log::info!("client disconnected because {reason:?}"); - if !silent { - self.send_raw_packet(ClientPacket::Disconnect)?; - } - self.client_id = None; - self.status = ClientStatus::Disconnected; - self.disconnect_reason = reason; - self.event_queue.push_back(ClientEvent::Disconnected(self.disconnect_reason.clone())); - Ok(()) - } - - fn reset_timeout(&mut self) { - self.timeout = Instant::now(); - } - - #[inline] - pub fn connect(&mut self) -> Result<()> { - log::info!("Client connecting.."); - if self.status != ClientStatus::Disconnected { - bail!("Not Disconnected"); - } - self.status = ClientStatus::Connecting; - self.last_heartbeat = Instant::now(); - self.reset_timeout(); - self.socket.connect(self.addr)?; - self.send_raw_packet(ClientPacket::Connect{ - user_protocol: self.config.protocol_id, - inner_protocol: PROTOCOL_ID, - })?; - Ok(()) - } - - #[inline] - pub fn disconnect(&mut self) -> Result<()> { - if self.status != ClientStatus::Connected { - bail!("Not Connected"); - } - self.disconnect_inner(DisconnectReason::ClientDisconnected, false)?; - Ok(()) - } - - #[inline] - pub fn set_nonblocking(&mut self, is_nonblocking: bool) -> Result<()> { - self.socket.set_nonblocking(is_nonblocking)?; - Ok(()) - } - - #[inline] - pub fn get_status(&self) -> ClientStatus { - self.status - } - - #[inline] - pub fn is_connected(&self) -> bool { - self.status == ClientStatus::Connected - } - - #[inline] - pub fn is_connecting(&self) -> bool { - self.status == ClientStatus::Connecting - } - - #[inline] - pub fn is_disconnected(&self) -> bool { - self.status == ClientStatus::Disconnected - } - - //Return true if the client has not made any connection attempts yet - #[inline] - pub fn has_not_made_connection_attempts(&self) -> bool { - matches!(self.status, ClientStatus::Disconnected) && - matches!(self.disconnect_reason, DisconnectReason::NotConnected) - } - - #[inline] - pub fn send_message(&self, message: S) -> Result<()> { - if self.status != ClientStatus::Connected { - bail!("Not Connected"); - } - self.send_raw_packet(ClientPacket::Data(message))?; - Ok(()) - } - - #[inline] - pub fn update(&mut self) -> Result<()> { // , callback: fn(ClientEvent) -> Result<()> - if self.status == ClientStatus::Disconnected { - return Ok(()) - } - if self.timeout.elapsed() > self.config.timeout { - log::warn!("Client timed out"); - //We don't care if this packet actually gets sent because the server is likely dead - let _ = self.disconnect_inner(DisconnectReason::Timeout, false).map_err(|_| { - log::warn!("Failed to send disconnect packet"); - }); - return Ok(()) - } - if self.last_heartbeat.elapsed() > self.config.heartbeat_interval { - log::trace!("Sending heartbeat packet"); - self.send_raw_packet(ClientPacket::Heartbeat)?; - self.last_heartbeat = Instant::now(); - } - //receive - let mut buf = [0; PACKET_SIZE]; - loop { - match self.socket.recv(&mut buf) { - Ok(length) => { - //TODO check the first byte of the raw data instead of decoding? - let (packet, _): (IdServerPacket, _) = bincode::decode_from_slice(&buf[..length], BINCODE_CONFIG)?; - let IdServerPacket(user_id, packet) = packet; - if self.client_id.map(|x| Some(x) != user_id).unwrap_or_default() { - return Ok(()) - } - self.reset_timeout(); - match packet { - ServerPacket::Connected(client_id) => { - log::info!("client connected with id {client_id}"); - self.client_id = Some(client_id); - self.status = ClientStatus::Connected; - self.event_queue.push_back(ClientEvent::Connected(client_id)); - return Ok(()) - }, - ServerPacket::Disconnected(reason) => { - log::info!("client kicked: {reason}"); - let reason = DisconnectReason::KickedByServer(Some(reason)); - self.disconnect_inner(reason, true)?; //this should never fail but we're handling the error anyway - return Ok(()) - }, - ServerPacket::Data(message) => { - self.event_queue.push_back(ClientEvent::MessageReceived(message)); - self.timeout = Instant::now(); - }, - ServerPacket::Heartbeat => { - self.timeout = Instant::now(); - }, - ServerPacket::ProtoDisconnect => { - let reason = DisconnectReason::InvalidProtocolId; - self.disconnect_inner(reason, true)?; //this should never fail but we're handling the error anyway - return Ok(()); - } - } - }, - Err(error) if error.kind() != ErrorKind::WouldBlock => { - match error.kind() { - ErrorKind::ConnectionReset => { - log::error!("Connection interrupted"); - self.disconnect_inner(DisconnectReason::ConnectionReset, true)?; - }, - _ => { - log::error!("IO error {error}"); - return Err(error.into()); - }, - } - }, - _ => break, - } - } - Ok(()) - } - - #[inline] - pub fn pop_event(&mut self) -> Option> { - self.event_queue.pop_front() - } - - #[inline] - pub fn process_events(&mut self) -> DrainDeque> { - self.event_queue.drain(..) - } -} diff --git a/kubi-udp/src/common.rs b/kubi-udp/src/common.rs deleted file mode 100644 index be598a7..0000000 --- a/kubi-udp/src/common.rs +++ /dev/null @@ -1,11 +0,0 @@ -use std::num::NonZeroU8; - -pub type ClientId = NonZeroU8; -pub type ClientIdRepr = u8; - -pub const MAX_CLIENTS: usize = u8::MAX as _; - -pub const PROTOCOL_ID: u16 = 1; -pub const DEFAULT_USER_PROTOCOL_ID: u16 = 0xffff; - -pub const PACKET_SIZE: usize = u16::MAX as usize; diff --git a/kubi-udp/src/lib.rs b/kubi-udp/src/lib.rs deleted file mode 100644 index 82588e3..0000000 --- a/kubi-udp/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub mod client; -pub mod server; -pub(crate) mod packet; -pub(crate) mod common; -pub use common::ClientId; -pub use common::ClientIdRepr; -pub use common::MAX_CLIENTS; - -//pub(crate) trait Serializable: bincode::Encode + bincode::Decode {} -pub(crate) const BINCODE_CONFIG: bincode::config::Configuration = bincode::config::standard() - .with_little_endian() - .with_variable_int_encoding() - .skip_fixed_array_length(); diff --git a/kubi-udp/src/packet.rs b/kubi-udp/src/packet.rs deleted file mode 100644 index b5eff11..0000000 --- a/kubi-udp/src/packet.rs +++ /dev/null @@ -1,33 +0,0 @@ -use bincode::{Encode, Decode}; -use crate::common::ClientId; - -pub trait Message: Encode + Decode + Clone {} -impl Message for T {} - -#[repr(u8)] -#[derive(Encode, Decode)] -pub enum ClientPacket where T: Message { - Connect { - inner_protocol: u16, - user_protocol: u16, - }, //should always stay 0! - Data(T), - Disconnect, - Heartbeat, -} - -#[derive(Encode, Decode)] -pub struct IdClientPacket(pub Option, pub ClientPacket); - -#[repr(u8)] -#[derive(Encode, Decode)] -pub enum ServerPacket where T: Message { - ProtoDisconnect = 0, - Data(T), - Disconnected(String), - Connected(ClientId), - Heartbeat, -} - -#[derive(Encode, Decode)] -pub struct IdServerPacket(pub Option, pub ServerPacket); diff --git a/kubi-udp/src/server.rs b/kubi-udp/src/server.rs deleted file mode 100644 index 337f292..0000000 --- a/kubi-udp/src/server.rs +++ /dev/null @@ -1,266 +0,0 @@ -use std::{ - net::{UdpSocket, SocketAddr}, - time::{Instant, Duration}, - marker::PhantomData, - collections::{VecDeque, vec_deque::Drain as DrainDeque}, - io::ErrorKind -}; -use anyhow::{Result, Error, bail}; -use hashbrown::HashMap; -use nohash_hasher::BuildNoHashHasher; -use crate::{ - BINCODE_CONFIG, - common::{ClientId, ClientIdRepr, MAX_CLIENTS, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID, PACKET_SIZE}, - packet::{IdClientPacket, ClientPacket, ServerPacket, IdServerPacket, Message} -}; - -//i was feeling a bit sick while writing most of this please excuse me for my terrible code :3 - -pub struct ConnectedClient { - id: ClientId, - addr: SocketAddr, - timeout: Instant, -} - -#[derive(Clone, Copy, Debug)] -pub struct ServerConfig { - pub max_clients: usize, - pub client_timeout: Duration, - pub protocol_id: u16, -} -impl Default for ServerConfig { - fn default() -> Self { - Self { - max_clients: MAX_CLIENTS, - client_timeout: Duration::from_secs(5), - protocol_id: DEFAULT_USER_PROTOCOL_ID, - } - } -} - -pub enum ServerEvent where T: Message { - Connected(ClientId), - Disconnected(ClientId), - MessageReceived { - from: ClientId, - message: T - } -} - -pub struct Server where S: Message, R: Message { - socket: UdpSocket, - clients: HashMap>, - config: ServerConfig, - event_queue: VecDeque>, - _s: PhantomData, -} -impl Server where S: Message, R: Message { - pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result { - assert!(config.max_clients <= MAX_CLIENTS, "max_clients value exceeds the maximum allowed amount of clients"); - if config.protocol_id == 0 { - log::warn!("Warning: using 0 as protocol_id is not recommended"); - } - if config.protocol_id == DEFAULT_USER_PROTOCOL_ID { - log::warn!("Warning: using default protocol_id is not recommended"); - } - let socket = UdpSocket::bind(addr)?; - socket.set_nonblocking(true)?; - Ok(Self { - config, - socket, - clients: HashMap::with_capacity_and_hasher(MAX_CLIENTS, BuildNoHashHasher::default()), - event_queue: VecDeque::new(), - _s: PhantomData, - }) - } - - - fn send_to_addr_inner(socket: &UdpSocket, addr: SocketAddr, packet: IdServerPacket) -> Result<()> { - let bytes = bincode::encode_to_vec(packet, BINCODE_CONFIG)?; - socket.send_to(&bytes, addr)?; - Ok(()) - } - - fn send_to_addr(&self, addr: SocketAddr, packet: IdServerPacket) -> Result<()> { - Self::send_to_addr_inner(&self.socket, addr, packet) - } - - fn send_packet(&self, packet: IdServerPacket) -> Result<()> { - let Some(id) = packet.0 else { - bail!("send_to_client call without id") - }; - let Some(client) = self.clients.get(&id) else { - bail!("client with id {id} doesn't exist") - }; - self.send_to_addr(client.addr, packet)?; - Ok(()) - } - - fn add_client(&mut self, addr: SocketAddr) -> Result { - let Some(id) = (1..=self.config.max_clients) - .map(|x| ClientId::new(x as _).unwrap()) - .find(|i| !self.clients.contains_key(i)) else { - bail!("Server full"); - }; - if self.clients.iter().any(|x| x.1.addr == addr) { - bail!("Already connected from the same address"); - } - self.clients.insert(id, ConnectedClient { - id, - addr, - timeout: Instant::now(), - }); - Ok(id) - } - - fn disconnect_client_inner(&mut self, id: ClientId, reason: String) -> Result<()> { - let result = self.send_packet(IdServerPacket( - Some(id), ServerPacket::Disconnected(reason) - )); - self.clients.remove(&id); - result - } - - pub fn kick_client(&mut self, id: ClientId, reason: String) -> Result<()> { - if !self.clients.contains_key(&id) { - bail!("Already disconnected") - } - self.disconnect_client_inner(id, reason)?; - Ok(()) - } - - pub fn shutdown(mut self) -> Result<()> { - let clients = self.clients.keys().copied().collect::>(); - for id in clients { - self.kick_client(id, "Server is shutting down".into())?; - } - Ok(()) - } - - pub fn send_message(&mut self, id: ClientId, message: S) -> Result<()> { - self.send_packet(IdServerPacket(Some(id), ServerPacket::Data(message)))?; - Ok(()) - } - pub fn multicast_message(&mut self, clients: impl IntoIterator, message: S) -> Vec { - //TODO use actual udp multicast - let mut errors = Vec::with_capacity(0); - for client in clients { - if let Err(error) = self.send_message(client, message.clone()) { - log::error!("Message broadcast failed for id {client}"); - errors.push(error); - } - } - errors - } - pub fn broadcast_message(&mut self, message: S) -> Vec { - let ids = self.clients.keys().copied().collect::>(); - self.multicast_message(ids, message) - } - pub fn broadcast_message_except(&mut self, except: ClientId, message: S) -> Vec { - let ids = self.clients.keys().copied().filter(|&k| k != except).collect::>(); - self.multicast_message(ids, message) - } - - pub fn update(&mut self) -> Result<()> { - //kick inactive clients - self.clients.retain(|&id, client| { - if client.timeout.elapsed() > self.config.client_timeout { - if let Err(_) = Self::send_to_addr_inner(&self.socket, client.addr, IdServerPacket( - Some(id), ServerPacket::Disconnected("Timed out".into()) - )) { - log::warn!("Client {id} timed out and we failed to send the kick packet. This shouldn't reaally matter") - } else { - log::info!("Client {id} timed out"); - } - return false - } - true - }); - - let mut buf = [0; PACKET_SIZE]; - loop { - match self.socket.recv_from(&mut buf) { - Ok((len, addr)) => { - if let Ok(packet) = bincode::decode_from_slice(&buf[..len], BINCODE_CONFIG) { - let (packet, _): (IdClientPacket, _) = packet; - let IdClientPacket(id, packet) = packet; - match id { - Some(id) => { - if !self.clients.contains_key(&id) { - bail!("Client with id {id} doesn't exist"); - } - if self.clients.get(&id).unwrap().addr != addr { - bail!("Client addr doesn't match"); - } - match packet { - ClientPacket::Data(data) => { - self.event_queue.push_back(ServerEvent::MessageReceived { - from: id, - message: data, - }); - } - ClientPacket::Disconnect => { - log::info!("Client {id} disconnected"); - self.event_queue.push_back(ServerEvent::Disconnected(id)); - self.disconnect_client_inner(id, "Disconnected".into())?; - }, - ClientPacket::Heartbeat => { - self.clients.get_mut(&id).unwrap().timeout = Instant::now(); - self.send_packet(IdServerPacket(Some(id), ServerPacket::Heartbeat))?; - }, - ClientPacket::Connect{..} => bail!("Client already connected"), - } - }, - None => { - match packet { - ClientPacket::Connect { user_protocol, inner_protocol } => { - if (inner_protocol != PROTOCOL_ID) || (user_protocol != self.config.protocol_id ) { - log::error!("Client conenction refused: Invalid protocol id"); - self.send_to_addr(addr, - IdServerPacket(None, ServerPacket::ProtoDisconnect) - )?; - continue; - } - - match self.add_client(addr) { - Ok(id) => { - log::info!("Client with id {id} connected"); - self.event_queue.push_back(ServerEvent::Connected(id)); - self.send_to_addr(addr, - IdServerPacket(None, ServerPacket::Connected(id)) - )?; - }, - Err(error) => { - let reason = error.to_string(); - log::error!("Client connection failed: {reason}"); - self.send_to_addr(addr, IdServerPacket( - None, ServerPacket::Disconnected(reason) - ))?; - } - } - }, - _ => bail!("Invalid packet type for non-id packet") - } - } - } - } else { - bail!("Corrupted packet received"); - } - }, - Err(error) if error.kind() != ErrorKind::WouldBlock => { - log::error!("IO error {}", error); - // return Err(error.into()); - }, - _ => break, - } - } - Ok(()) - } - - pub fn pop_event(&mut self) -> Option> { - self.event_queue.pop_front() - } - pub fn process_events(&mut self) -> DrainDeque> { - self.event_queue.drain(..) - } -} diff --git a/kubi-udp/tests/test.rs b/kubi-udp/tests/test.rs deleted file mode 100644 index 7deb52c..0000000 --- a/kubi-udp/tests/test.rs +++ /dev/null @@ -1,93 +0,0 @@ -use kubi_udp::{ - server::{Server, ServerConfig, ServerEvent}, - client::{Client, ClientConfig, ClientEvent}, -}; -use std::{thread, time::Duration}; - -const TEST_ADDR: &str = "127.0.0.1:22342"; - -type CtsMessage = u32; -type StcMessage = u64; - -const CTS_MSG: CtsMessage = 0xbeef_face; -const STC_MSG: StcMessage = 0xdead_beef_cafe_face; - -#[test] -fn test_connection() { - //Init logging - kubi_logging::init(); - - //Create server and client - let mut server: Server = Server::bind( - TEST_ADDR.parse().expect("Invalid TEST_ADDR"), - ServerConfig::default() - ).expect("Failed to create server"); - let mut client: Client = Client::new( - TEST_ADDR.parse().unwrap(), - ClientConfig::default() - ).expect("Failed to create client"); - - //Start server update thread - let server_handle = thread::spawn(move || { - let mut message_received = false; - loop { - server.update().unwrap(); - let events: Vec<_> = server.process_events().collect(); - for event in events { - match event { - ServerEvent::Connected(id) => { - assert_eq!(id.get(), 1, "Unexpected client id"); - server.send_message(id, STC_MSG).unwrap(); - }, - ServerEvent::Disconnected(id) => { - assert!(message_received, "Client {id} disconnected from the server before sending the message"); - return; - }, - ServerEvent::MessageReceived { from, message } => { - log::info!("server received message"); - assert_eq!(message, CTS_MSG, "Received message not equal"); - message_received = true; - }, - _ => () - } - } - } - }); - - //Wait a bit - thread::sleep(Duration::from_secs(1)); - - //Connect client - client.connect().expect("Client connect failed"); - - //Start updating the client - let client_handle = thread::spawn(move || { - let mut message_received = false; - loop { - client.update().unwrap(); - let events: Vec<_> = client.process_events().collect(); - for event in events { - match event { - ClientEvent::Connected(id) => { - assert_eq!(id.get(), 1, "Unexpected client id"); - client.send_message(CTS_MSG).unwrap(); - }, - ClientEvent::Disconnected(reason) => { - assert!(message_received, "Client lost connection to the server before sending the message with reason: {reason:?}"); - return; - }, - ClientEvent::MessageReceived(data) => { - log::info!("client received message"); - assert_eq!(data, STC_MSG, "Received message not equal"); - message_received = true; - client.disconnect().unwrap(); - }, - _ => () - } - } - } - }); - - server_handle.join().unwrap(); - client_handle.join().unwrap(); -} diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 6b16766..519a6ba 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -6,7 +6,6 @@ publish = false [dependencies] kubi-shared = { path = "../kubi-shared" } -kubi-udp = { path = "../kubi-udp" } kubi-logging = { path = "../kubi-logging" } log = "*" glium = "0.32" diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 6630c1c..850ed78 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -1,7 +1,6 @@ use shipyard::{Unique, AllStoragesView, UniqueView, UniqueViewMut, Workload, IntoWorkload, EntitiesViewMut, Component, ViewMut, SystemModificator, View, IntoIter, WorkloadModificator}; use glium::glutin::event_loop::ControlFlow; use std::net::SocketAddr; -use kubi_udp::client::{Client, ClientConfig, ClientEvent}; use kubi_shared::networking::{ messages::{ClientToServerMessage, ServerToClientMessage}, state::ClientJoinState diff --git a/kubi/src/world/tasks.rs b/kubi/src/world/tasks.rs index 0bc05ad..713c460 100644 --- a/kubi/src/world/tasks.rs +++ b/kubi/src/world/tasks.rs @@ -15,7 +15,6 @@ use crate::{ rendering::world::ChunkVertex, networking::NetworkEvent, }; -use kubi_udp::client::ClientEvent; pub enum ChunkTask { LoadChunk { From e5041aaa1afc95763ba1df90847e3497688b3a01 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 01:31:38 +0100 Subject: [PATCH 150/160] Client-side migrated --- .vscode/settings.json | 4 +- Cargo.lock | 115 +++++++++++++++++++------ kubi-server/src/server.rs | 1 - kubi-server/src/world.rs | 2 +- kubi-server/src/world/tasks.rs | 3 +- kubi-shared/Cargo.toml | 5 +- kubi-shared/src/block.rs | 6 +- kubi-shared/src/lib.rs | 1 + kubi-shared/src/networking/messages.rs | 77 ++++++++++------- kubi-shared/src/queue.rs | 11 +++ kubi-shared/src/worldgen.rs | 10 +-- kubi/Cargo.toml | 2 + kubi/src/block_placement.rs | 11 ++- kubi/src/networking.rs | 91 ++++++++++--------- kubi/src/world/loading.rs | 27 +++--- kubi/src/world/queue.rs | 17 +--- kubi/src/world/tasks.rs | 29 ++++--- 17 files changed, 257 insertions(+), 155 deletions(-) create mode 100644 kubi-shared/src/queue.rs diff --git a/.vscode/settings.json b/.vscode/settings.json index 4fb2774..344b96f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,8 @@ { "editor.tabSize": 2, "rust-analyzer.diagnostics.disabled": [ - "unresolved-method" //rust-analyzer issue #14269 + //rust-analyzer issue #14269, + "unresolved-method", + "unresolved-import" ] } diff --git a/Cargo.lock b/Cargo.lock index b2c5b20..ad34951 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,6 +66,15 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "atomic-polyfill" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" +dependencies = [ + "critical-section", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -87,25 +96,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "bincode" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb50c5a2ef4b9b1e7ae73e3a73b52ea24b20312d629f9c4df28260b7ad2c3c4" -dependencies = [ - "bincode_derive", - "serde", -] - -[[package]] -name = "bincode_derive" -version = "2.0.0-rc.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a45a23389446d2dd25dc8e73a7a3b3c43522b630cac068927f0649d43d719d2" -dependencies = [ - "virtue", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -203,6 +193,12 @@ dependencies = [ "cc", ] +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "cocoa" version = "0.24.1" @@ -302,6 +298,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "critical-section" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6548a0ad5d2549e111e1f6a11a6c2e2d00ce6a3dafe22948d67c2b443f775e52" + [[package]] name = "crossbeam-channel" version = "0.5.7" @@ -753,6 +755,15 @@ dependencies = [ "gl_generator", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -771,6 +782,20 @@ dependencies = [ "ahash 0.8.3", ] +[[package]] +name = "heapless" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" +dependencies = [ + "atomic-polyfill", + "hash32", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + [[package]] name = "heck" version = "0.4.1" @@ -908,9 +933,11 @@ dependencies = [ "kubi-shared", "log", "nohash-hasher", + "postcard", "rayon", "shipyard", "strum", + "uflow", "winapi", ] @@ -945,11 +972,12 @@ name = "kubi-shared" version = "0.1.0" dependencies = [ "anyhow", - "bincode", "bracket-noise", "glam", + "postcard", "rand", "rand_xoshiro", + "serde", "shipyard", "strum", ] @@ -1374,6 +1402,17 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "postcard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfa512cd0d087cc9f99ad30a1bf64795b67871edbead083ffc3a4dfafa59aa00" +dependencies = [ + "cobs", + "heapless", + "serde", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1529,6 +1568,15 @@ version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.36.9" @@ -1593,6 +1641,12 @@ dependencies = [ "tiny-skia", ] +[[package]] +name = "semver" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" + [[package]] name = "serde" version = "1.0.152" @@ -1717,6 +1771,12 @@ dependencies = [ "lock_api", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strsim" version = "0.10.0" @@ -1850,6 +1910,15 @@ dependencies = [ "winnow", ] +[[package]] +name = "uflow" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be4d71c1c106a57b0333ac2c28bd4521e0b16a2b98fe84405cdf7f544be46b6" +dependencies = [ + "rand", +] + [[package]] name = "unicode-ident" version = "1.0.8" @@ -1874,12 +1943,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "virtue" -version = "0.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b60dcd6a64dd45abf9bd426970c9843726da7fc08f44cd6fcebf68c21220a63" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/kubi-server/src/server.rs b/kubi-server/src/server.rs index c9bde00..f576b3e 100644 --- a/kubi-server/src/server.rs +++ b/kubi-server/src/server.rs @@ -1,5 +1,4 @@ use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut}; -use kubi_udp::server::{Server, ServerConfig, ServerEvent}; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; use std::time::Duration; use crate::config::ConfigTable; diff --git a/kubi-server/src/world.rs b/kubi-server/src/world.rs index c7de485..4124e7b 100644 --- a/kubi-server/src/world.rs +++ b/kubi-server/src/world.rs @@ -86,7 +86,7 @@ fn process_finished_tasks( server.0.send_message(subscriber, ServerToClientMessage::ChunkResponse { chunk: chunk_position.to_array(), data: blocks.clone(), - queued: queue.iter().map(|item| (item.position.to_array(), item.block_type)).collect() + queued: queue }).map_err(log_error).ok(); } log::debug!("Chunk {chunk_position} loaded, {} subs", chunk.subscriptions.len()); diff --git a/kubi-server/src/world/tasks.rs b/kubi-server/src/world/tasks.rs index fd2d120..8094632 100644 --- a/kubi-server/src/world/tasks.rs +++ b/kubi-server/src/world/tasks.rs @@ -5,7 +5,8 @@ use rayon::{ThreadPool, ThreadPoolBuilder}; use anyhow::Result; use kubi_shared::{ chunk::BlockData, - worldgen::{QueuedBlock, generate_world} + worldgen::generate_world, + queue::QueuedBlock, }; pub enum ChunkTask { diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 7a4f1cc..be2079d 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -10,7 +10,8 @@ publish = false glam = { version = "0.23", features = ["debug-glam-assert", "fast-math", "serde"] } shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66" } strum = { version = "0.24", features = ["derive"] } -bincode = "2.0.0-rc" +postcard = { version = "1.0", features = ["alloc"] } +serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } anyhow = "1.0" bracket-noise = "0.8" rand = { version = "0.8", default_features = false, features = ["std", "min_const_gen"] } @@ -18,4 +19,4 @@ rand_xoshiro = "0.6" [features] default = [] -nightly = ["rand/nightly", "rand/simd_support"] +nightly = ["rand/nightly", "rand/simd_support", "serde/unstable"] diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index 5afc8db..b2f0bee 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -1,7 +1,7 @@ -use bincode::{Encode, Decode}; +use serde::{Serialize, Deserialize}; use strum::EnumIter; -#[derive(Clone, Copy, Debug, EnumIter)] +#[derive(Serialize, Deserialize, Clone, Copy, Debug, EnumIter)] #[repr(u8)] pub enum BlockTexture { Stone, @@ -22,7 +22,7 @@ pub enum BlockTexture { WaterSolid, } -#[derive(Encode, Decode, Clone, Copy, Debug, PartialEq, Eq, EnumIter)] +#[derive(Serialize, Deserialize, Clone, Copy, Debug, PartialEq, Eq, EnumIter)] #[repr(u8)] pub enum Block { Air, diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs index 2f1da39..79f16a7 100644 --- a/kubi-shared/src/lib.rs +++ b/kubi-shared/src/lib.rs @@ -4,3 +4,4 @@ pub mod worldgen; pub mod chunk; pub mod transform; pub mod entity; +pub mod queue; diff --git a/kubi-shared/src/networking/messages.rs b/kubi-shared/src/networking/messages.rs index c8b17a9..9213547 100644 --- a/kubi-shared/src/networking/messages.rs +++ b/kubi-shared/src/networking/messages.rs @@ -1,30 +1,63 @@ use std::num::NonZeroUsize; -use bincode::{Encode, Decode}; -use crate::{chunk::BlockData, block::Block}; +use serde::{Serialize, Deserialize}; +use crate::{chunk::BlockData, queue::QueuedBlock}; -type IVec3Arr = [i32; 3]; -type Vec3Arr = [f32; 3]; -type QuatArr = [f32; 3]; +pub type IVec3Arr = [i32; 3]; +pub type Vec3Arr = [f32; 3]; +pub type QuatArr = [f32; 3]; -pub const PROTOCOL_ID: u16 = 1; +pub const PROTOCOL_ID: u16 = 2; -#[derive(Encode, Decode, Clone)] +pub const C_CLIENT_HELLO: u8 = 0; +pub const C_POSITION_CHANGED: u8 = 1; +pub const C_CHUNK_SUB_REQUEST: u8 = 2; + +#[derive(Serialize, Deserialize, Clone)] +#[repr(u8)] pub enum ClientToServerMessage { ClientHello { username: String, password: Option, - }, + } = C_CLIENT_HELLO, PositionChanged { position: Vec3Arr, velocity: Vec3Arr, direction: QuatArr, - }, + } = C_POSITION_CHANGED, ChunkSubRequest { chunk: IVec3Arr, - }, + } = C_CHUNK_SUB_REQUEST, } -#[derive(Encode, Decode, Clone)] +pub const S_SERVER_HELLO: u8 = 0; +pub const S_SERVER_FUCK_OFF: u8 = 1; +pub const S_PLAYER_POSITION_CHANGED: u8 = 2; +pub const S_CHUNK_RESPONSE: u8 = 3; + +#[derive(Serialize, Deserialize, Clone)] +#[repr(u8)] +pub enum ServerToClientMessage { + ServerHello { + init: InitData + } = S_SERVER_HELLO, + ServerFuckOff { + reason: String, + } = S_SERVER_FUCK_OFF, + PlayerPositionChanged { + client_id: u8, + position: Vec3Arr, + direction: QuatArr, + } = S_PLAYER_POSITION_CHANGED, + ChunkResponse { + chunk: IVec3Arr, + data: BlockData, + queued: Vec, + } = S_CHUNK_RESPONSE, +} + +//--- + +#[derive(Serialize, Deserialize, Clone)] pub struct UserInitData { pub client_id: NonZeroUsize, //maybe use the proper type instead pub username: String, @@ -33,27 +66,7 @@ pub struct UserInitData { pub direction: QuatArr, } -#[derive(Encode, Decode, Clone)] +#[derive(Serialize, Deserialize, Clone)] pub struct InitData { pub users: Vec } - -#[derive(Encode, Decode, Clone)] -pub enum ServerToClientMessage { - ServerHello { - init: InitData - }, - ServerFuckOff { - reason: String, - }, - PlayerPositionChanged { - client_id: u8, - position: Vec3Arr, - direction: QuatArr, - }, - ChunkResponse { - chunk: IVec3Arr, - data: BlockData, - queued: Vec<(IVec3Arr, Block)>, - } -} diff --git a/kubi-shared/src/queue.rs b/kubi-shared/src/queue.rs new file mode 100644 index 0000000..7216756 --- /dev/null +++ b/kubi-shared/src/queue.rs @@ -0,0 +1,11 @@ +use glam::IVec3; +use serde::{Serialize, Deserialize}; +use crate::block::Block; + +#[derive(Serialize, Deserialize, Clone, Copy, Debug)] +pub struct QueuedBlock { + pub position: IVec3, + pub block_type: Block, + /// Only replace air blocks + pub soft: bool, +} diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index 09cb993..56fd807 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -4,7 +4,8 @@ use glam::{IVec3, ivec3, Vec3Swizzles, IVec2}; use rand_xoshiro::Xoshiro256StarStar; use crate::{ chunk::{BlockData, CHUNK_SIZE}, - block::Block + block::Block, + queue::QueuedBlock, }; fn mountain_ramp(mut x: f32) -> f32 { @@ -29,10 +30,6 @@ fn local_y_position(height: i32, chunk_position: IVec3) -> Option { (0..CHUNK_SIZE as i32).contains(&position).then_some(position as usize) } -pub struct QueuedBlock { - pub position: IVec3, - pub block_type: Block, -} pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec) { let offset = chunk_position * CHUNK_SIZE as i32; @@ -47,7 +44,8 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> (BlockData, Vec); +pub struct UdpClient(pub Client); #[derive(Component)] -pub struct NetworkEvent(pub ClientEvent); +pub struct NetworkEvent(pub ClientEvent); -fn create_client( +impl NetworkEvent { + ///Checks if postcard-encoded message has a type + pub fn is_message_of_type(&self) -> bool { + let ClientEvent::Receive(data) = &self.0 else { return false }; + if data.len() == 0 { return false } + data[0] == T + } +} + +#[derive(Component)] +pub struct NetworkMessageEvent(pub ServerToClientMessage); + +fn connect_client( storages: AllStoragesView ) { log::info!("Creating client"); let address = storages.borrow::>().unwrap(); - storages.add_unique(UdpClient(Client::new( - address.0, - ClientConfig::default() - ).unwrap())); + let client = Client::connect(address.0, ClientConfig::default()).expect("Client connection failed"); + storages.add_unique(UdpClient(client)); storages.add_unique(ClientJoinState::Disconnected); } -fn connect_client( - mut client: UniqueViewMut -) { - log::info!("Connect called"); - client.0.connect().unwrap(); -} - -fn should_connect( - client: UniqueView -) -> bool { - client.0.has_not_made_connection_attempts() -} - -fn update_client( - mut client: UniqueViewMut, -) { - client.0.update().unwrap(); -} - -fn insert_client_events( +fn poll_client( mut client: UniqueViewMut, mut entities: EntitiesViewMut, mut events: ViewMut, @@ -62,7 +54,7 @@ fn insert_client_events( entities.bulk_add_entity(( &mut events, &mut network_events, - ), client.0.process_events().map(|event| { + ), client.0.step().map(|event| { (EventComponent, NetworkEvent(event)) })); } @@ -75,13 +67,19 @@ fn set_client_join_state_to_connected( } fn say_hello( - client: UniqueViewMut, + mut client: UniqueViewMut, ) { log::info!("Authenticating"); - client.0.send_message(ClientToServerMessage::ClientHello { - username: "Sbeve".into(), - password: None - }).unwrap(); + client.0.send( + postcard::to_allocvec( + &ClientToServerMessage::ClientHello { + username: "Sbeve".into(), + password: None + } + ).unwrap().into_boxed_slice(), + 0, + uflow::SendMode::Reliable + ); } fn check_server_hello_response( @@ -89,20 +87,20 @@ fn check_server_hello_response( mut join_state: UniqueViewMut ) { for event in network_events.iter() { - if let ClientEvent::MessageReceived(ServerToClientMessage::ServerHello { init }) = &event.0 { + if let ClientEvent::Receive(data) = &event.0 { + log::info!("Joined the server!"); //TODO handle init data *join_state = ClientJoinState::Joined; + return; } } } pub fn update_networking() -> Workload { ( - create_client.run_if_missing_unique::(), - connect_client.run_if(should_connect), - update_client, - insert_client_events, + connect_client.run_if_missing_unique::(), + poll_client, ( set_client_join_state_to_connected, say_hello, @@ -118,12 +116,19 @@ pub fn disconnect_on_exit( mut client: UniqueViewMut, ) { if let Some(ControlFlow::ExitWithCode(_)) = control_flow.0 { - client.0.set_nonblocking(false).expect("Failed to switch socket to blocking mode"); - if let Err(error) = client.0.disconnect() { - log::error!("failed to disconnect: {}", error); - } else { + if client.0.is_active() { + client.0.flush(); + client.0.disconnect(); + while client.0.is_active() { client.0.step(); } log::info!("Client disconnected"); + } else { + log::info!("Client inactive") } + // if let Err(error) = client.0. { + // log::error!("failed to disconnect: {}", error); + // } else { + // log::info!("Client disconnected"); + // } } } @@ -132,7 +137,7 @@ pub fn disconnect_on_exit( fn if_just_connected( network_events: View, ) -> bool { - network_events.iter().any(|event| matches!(&event.0, ClientEvent::Connected(_))) + network_events.iter().any(|event| matches!(&event.0, ClientEvent::Connect)) } fn is_join_state( diff --git a/kubi/src/world/loading.rs b/kubi/src/world/loading.rs index 76d67f3..154782d 100644 --- a/kubi/src/world/loading.rs +++ b/kubi/src/world/loading.rs @@ -2,6 +2,8 @@ use glam::{IVec3, ivec3}; use glium::{VertexBuffer, IndexBuffer, index::PrimitiveType}; use kubi_shared::networking::messages::ClientToServerMessage; use shipyard::{View, UniqueView, UniqueViewMut, IntoIter, Workload, IntoWorkload, NonSendSync, track}; +use kubi_shared::queue::QueuedBlock; +use uflow::SendMode; use crate::{ player::MainPlayer, transform::Transform, @@ -14,7 +16,7 @@ use super::{ ChunkStorage, ChunkMeshStorage, chunk::{Chunk, DesiredChunkState, CHUNK_SIZE, ChunkMesh, CurrentChunkState, ChunkData}, tasks::{ChunkTaskManager, ChunkTaskResponse, ChunkTask}, - queue::{BlockUpdateQueue, BlockUpdateEvent}, + queue::BlockUpdateQueue }; const MAX_CHUNK_OPS_INGAME: usize = 6; @@ -120,7 +122,7 @@ fn unload_downgrade_chunks( fn start_required_tasks( task_manager: UniqueView, - udp_client: Option>, + mut udp_client: Option>, mut world: UniqueViewMut, ) { if !world.is_modified() { @@ -133,10 +135,14 @@ fn start_required_tasks( match chunk.desired_state { DesiredChunkState::Loaded | DesiredChunkState::Rendered if chunk.current_state == CurrentChunkState::Nothing => { //start load task - if let Some(client) = &udp_client { - client.0.send_message(ClientToServerMessage::ChunkSubRequest { - chunk: position.to_array() - }).unwrap(); + if let Some(client) = &mut udp_client { + client.0.send( + postcard::to_allocvec(&ClientToServerMessage::ChunkSubRequest { + chunk: position.to_array() + }).unwrap().into_boxed_slice(), + 0, + SendMode::Reliable + ); } else { task_manager.spawn_task(ChunkTask::LoadChunk { seed: 0xbeef_face_dead_cafe, @@ -208,12 +214,9 @@ fn process_completed_tasks( chunk.current_state = CurrentChunkState::Loaded; //push queued blocks - for event in queued { - queue.push(BlockUpdateEvent { - position: event.position, - value: event.block_type, - soft: true, - }); + //TODO use extend + for item in queued { + queue.push(item); } //increase ops counter diff --git a/kubi/src/world/queue.rs b/kubi/src/world/queue.rs index 670e909..eb9f346 100644 --- a/kubi/src/world/queue.rs +++ b/kubi/src/world/queue.rs @@ -1,26 +1,17 @@ use glam::{IVec3, ivec3}; -use kubi_shared::{block::Block, chunk::CHUNK_SIZE}; +use kubi_shared::{block::Block, chunk::CHUNK_SIZE, queue::QueuedBlock}; use shipyard::{UniqueViewMut, Unique}; - use super::ChunkStorage; -#[derive(Clone, Copy, Debug)] -pub struct BlockUpdateEvent { - pub position: IVec3, - pub value: Block, - //Only replace air blocks - pub soft: bool, -} - #[derive(Unique, Default, Clone)] pub struct BlockUpdateQueue { - queue: Vec + queue: Vec } impl BlockUpdateQueue { pub fn new() -> Self { Self::default() } - pub fn push(&mut self, event: BlockUpdateEvent) { + pub fn push(&mut self, event: QueuedBlock) { self.queue.push(event) } } @@ -35,7 +26,7 @@ pub fn apply_queued_blocks( if event.soft && *block != Block::Air { return false } - *block = event.value; + *block = event.block_type; //mark chunk as dirty let (chunk_pos, block_pos) = ChunkStorage::to_chunk_coords(event.position); let chunk = world.chunks.get_mut(&chunk_pos).expect("This error should never happen, if it does then something is super fucked up and the whole project needs to be burnt down."); diff --git a/kubi/src/world/tasks.rs b/kubi/src/world/tasks.rs index 713c460..3a50ea4 100644 --- a/kubi/src/world/tasks.rs +++ b/kubi/src/world/tasks.rs @@ -1,11 +1,12 @@ use flume::{Sender, Receiver}; use glam::IVec3; use kubi_shared::{ - networking::messages::ServerToClientMessage, - worldgen::QueuedBlock + networking::messages::{S_CHUNK_RESPONSE, ServerToClientMessage}, + queue::QueuedBlock }; use shipyard::{Unique, UniqueView, View, IntoIter}; use rayon::{ThreadPool, ThreadPoolBuilder}; +use uflow::client::Event as ClientEvent; use super::{ chunk::BlockData, mesh::{generate_mesh, data::MeshGenData}, @@ -82,16 +83,24 @@ pub fn inject_network_responses_into_manager_queue( events: View ) { for event in events.iter() { - if let ClientEvent::MessageReceived(ServerToClientMessage::ChunkResponse { chunk, data, queued }) = &event.0 { - let position = IVec3::from_array(*chunk); + if event.is_message_of_type::() { + let NetworkEvent(ClientEvent::Receive(data)) = &event else { unreachable!() }; + let ServerToClientMessage::ChunkResponse { + chunk, data, queued + } = postcard::from_bytes(data).expect("Chunk decode failed") else { unreachable!() }; manager.add_sussy_response(ChunkTaskResponse::LoadedChunk { - position, - chunk_data: data.clone(), - queued: queued.iter().map(|&(position, block_type)| QueuedBlock { - position: IVec3::from_array(position), - block_type - }).collect() + position: IVec3::from_array(chunk), + chunk_data: data, + queued }); } + // if let ClientEvent::MessageReceived(ServerToClientMessage::ChunkResponse { &chunk, data, queued }) = &event.0 { + // let position = IVec3::from_array(chunk); + // manager.add_sussy_response(ChunkTaskResponse::LoadedChunk { + // position, + // chunk_data: data.clone(), + // queued + // }); + // } } } From 765e360d44872ec881f847075c7d7e1478ba06fe Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 01:47:46 +0100 Subject: [PATCH 151/160] disable lint --- .vscode/settings.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 344b96f..dad53cc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,7 @@ "rust-analyzer.diagnostics.disabled": [ //rust-analyzer issue #14269, "unresolved-method", - "unresolved-import" + "unresolved-import", + "unresolved-field" ] } From 34a50c62b0bad1b98dac24a93c19c8e77d96da6a Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 17:27:53 +0100 Subject: [PATCH 152/160] change server stuff --- Cargo.lock | 3 +++ kubi-server/Cargo.toml | 7 +++++-- kubi-server/src/client.rs | 3 ++- kubi-server/src/server.rs | 1 + kubi-server/src/world/chunk.rs | 7 +++++-- kubi-shared/Cargo.toml | 2 +- kubi-shared/src/networking.rs | 1 + kubi-shared/src/networking/client.rs | 3 +++ 8 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 kubi-shared/src/networking/client.rs diff --git a/Cargo.lock b/Cargo.lock index ad34951..8a4cca4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -961,10 +961,13 @@ dependencies = [ "kubi-shared", "log", "nohash-hasher", + "postcard", + "rand", "rayon", "serde", "shipyard", "toml", + "uflow", ] [[package]] diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 3784589..6c6b67d 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -9,7 +9,7 @@ kubi-shared = { path = "../kubi-shared" } kubi-logging = { path = "../kubi-logging" } log = "*" shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66" } -serde = "1.0" +serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } toml = "0.7" glam = { version = "0.23", features = ["debug-glam-assert", "fast-math"] } hashbrown = "0.13" @@ -17,7 +17,10 @@ nohash-hasher = "0.2.0" anyhow = "1.0" rayon = "1.6" flume = "0.10" +rand = "0.8" +uflow = "0.7" +postcard = { version = "1.0", features = ["alloc"] } [features] default = [] -unstable = ["glam/core-simd"] +nightly = ["rand/nightly", "rand/simd_support", "serde/unstable", "glam/core-simd", "kubi-shared/nightly"] diff --git a/kubi-server/src/client.rs b/kubi-server/src/client.rs index 41423ba..086e398 100644 --- a/kubi-server/src/client.rs +++ b/kubi-server/src/client.rs @@ -1,11 +1,12 @@ use shipyard::{Component, EntityId}; use hashbrown::HashMap; use nohash_hasher::BuildNoHashHasher; +use kubi_shared::networking::client::ClientId; #[derive(Component)] pub struct Client(ClientId); -pub struct ClientMap(HashMap>); +pub struct ClientMap(HashMap>); impl ClientMap { pub fn new() -> Self { Self(HashMap::with_hasher(BuildNoHashHasher::default())) diff --git a/kubi-server/src/server.rs b/kubi-server/src/server.rs index f576b3e..b862a31 100644 --- a/kubi-server/src/server.rs +++ b/kubi-server/src/server.rs @@ -1,5 +1,6 @@ use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut}; use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; +use uflow::server::Server; use std::time::Duration; use crate::config::ConfigTable; diff --git a/kubi-server/src/world/chunk.rs b/kubi-server/src/world/chunk.rs index 8a26922..bfecbcd 100644 --- a/kubi-server/src/world/chunk.rs +++ b/kubi-server/src/world/chunk.rs @@ -1,7 +1,10 @@ use glam::IVec3; use hashbrown::HashSet; use nohash_hasher::BuildNoHashHasher; -use kubi_shared::chunk::BlockData; +use kubi_shared::{ + chunk::BlockData, + networking::client::ClientId +}; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ChunkState { @@ -14,7 +17,7 @@ pub struct Chunk { pub position: IVec3, pub state: ChunkState, pub blocks: Option, - pub subscriptions: HashSet>, + pub subscriptions: HashSet>, } impl Chunk { pub fn new(position: IVec3) -> Self { diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index be2079d..90617c0 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -19,4 +19,4 @@ rand_xoshiro = "0.6" [features] default = [] -nightly = ["rand/nightly", "rand/simd_support", "serde/unstable"] +nightly = ["rand/nightly", "rand/simd_support", "serde/unstable", "glam/core-simd"] diff --git a/kubi-shared/src/networking.rs b/kubi-shared/src/networking.rs index 4945d0c..05bff68 100644 --- a/kubi-shared/src/networking.rs +++ b/kubi-shared/src/networking.rs @@ -1,2 +1,3 @@ pub mod messages; pub mod state; +pub mod client; diff --git a/kubi-shared/src/networking/client.rs b/kubi-shared/src/networking/client.rs new file mode 100644 index 0000000..35f3744 --- /dev/null +++ b/kubi-shared/src/networking/client.rs @@ -0,0 +1,3 @@ +pub type ClientId = u16; +pub type ClientKey = u16; + From 56dd1a3bda9ec5459127b6852b920268458f3ab3 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 20:26:51 +0100 Subject: [PATCH 153/160] upgrade some server stuff to uflow --- kubi/README.md => README.md | 0 kubi-server/Cargo.toml | 2 +- kubi-server/src/main.rs | 12 ++++--- kubi-server/src/server.rs | 63 +++++++++++++++++++++++-------------- 4 files changed, 47 insertions(+), 30 deletions(-) rename kubi/README.md => README.md (100%) diff --git a/kubi/README.md b/README.md similarity index 100% rename from kubi/README.md rename to README.md diff --git a/kubi-server/Cargo.toml b/kubi-server/Cargo.toml index 6c6b67d..6fb5e3d 100644 --- a/kubi-server/Cargo.toml +++ b/kubi-server/Cargo.toml @@ -8,7 +8,7 @@ publish = false kubi-shared = { path = "../kubi-shared" } kubi-logging = { path = "../kubi-logging" } log = "*" -shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66" } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66", features = ["thread_local"] } serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } toml = "0.7" glam = { version = "0.23", features = ["debug-glam-assert", "fast-math"] } diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index fc24b57..a99dbf0 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -9,7 +9,7 @@ pub(crate) mod world; pub(crate) mod auth; use config::read_config; -use server::{bind_server, update_server, update_server_events}; +use server::{bind_server, update_server, log_server_errors}; use auth::authenticate_players; use world::{update_world, init_world}; @@ -24,10 +24,12 @@ fn initialize() -> Workload { fn update() -> Workload { ( update_server, - update_server_events, - authenticate_players, - update_world, - ).into_workload() + ( + log_server_errors, + authenticate_players, + update_world, + ).into_workload() + ).into_sequential_workload() } fn main() { diff --git a/kubi-server/src/server.rs b/kubi-server/src/server.rs index b862a31..8b84264 100644 --- a/kubi-server/src/server.rs +++ b/kubi-server/src/server.rs @@ -1,47 +1,62 @@ -use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut}; -use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage}; -use uflow::server::Server; -use std::time::Duration; +use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut, NonSendSync}; +use uflow::{server::{Server, Event as ServerEvent, Config as ServerConfig}, EndpointConfig}; use crate::config::ConfigTable; #[derive(Unique)] #[repr(transparent)] -pub struct UdpServer(pub Server); +pub struct UdpServer(pub Server); #[derive(Unique, Default)] -pub struct ServerEvents(pub Vec>); +pub struct ServerEvents(pub Vec); + +pub trait IsMessageOfType { + ///Checks if postcard-encoded message has a type + fn is_message_of_type(&self) -> bool; +} +impl IsMessageOfType for ServerEvent { + fn is_message_of_type(&self) -> bool { + let ServerEvent::Receive(_, data) = &self else { return false }; + if data.len() == 0 { return false } + data[0] == T + } +} pub fn bind_server( storages: AllStoragesView, ) { log::info!("Creating server..."); let config = storages.borrow::>().unwrap(); - let server: Server = Server::bind( + let server = Server::bind( config.server.address, - ServerConfig { - max_clients: config.server.max_clients, - client_timeout: Duration::from_millis(config.server.timeout_ms), + ServerConfig { + max_total_connections: config.server.max_clients, + max_active_connections: config.server.max_clients, + enable_handshake_errors: true, + endpoint_config: EndpointConfig { + active_timeout_ms: config.server.timeout_ms, + ..Default::default() + }, ..Default::default() } - ).unwrap(); - storages.add_unique(UdpServer(server)); + ).expect("Failed to create the server"); + storages.add_unique_non_send_sync(UdpServer(server)); storages.add_unique(ServerEvents::default()); } pub fn update_server( - mut server: UniqueViewMut -) { - if let Err(error) = server.0.update() { - log::error!("Server error: {error:?}") - } -} - -pub fn update_server_events( - mut server: UniqueViewMut, + mut server: NonSendSync>, mut events: UniqueViewMut, ) { - //drop current events events.0.clear(); - //fetch new ones - events.0.extend(server.0.process_events().rev()); + events.0.extend(server.0.step()); +} + +pub fn log_server_errors( + events: UniqueView, +) { + for event in &events.0 { + if let ServerEvent::Error(addr, error) = event { + log::error!("Server error addr: {addr} error: {error:?}"); + } + } } From b20c6fe552808d7ed90184ac0f58124f2f0ff341 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 21:10:48 +0100 Subject: [PATCH 154/160] restore basic auth services --- kubi-server/src/auth.rs | 106 +++++++++++++++++++++++++++------------- kubi-server/src/main.rs | 8 +-- 2 files changed, 75 insertions(+), 39 deletions(-) diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs index 3f10a61..13b3507 100644 --- a/kubi-server/src/auth.rs +++ b/kubi-server/src/auth.rs @@ -1,48 +1,84 @@ -use shipyard::{UniqueView, UniqueViewMut}; -use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage, InitData}; -use crate::{server::{ServerEvents, UdpServer}, config::ConfigTable, util::log_error}; +use shipyard::{UniqueView, UniqueViewMut, NonSendSync}; +use uflow::{server::Event as ServerEvent, SendMode}; +use kubi_shared::networking::messages::{ + ClientToServerMessage, + ServerToClientMessage, + InitData, + C_CLIENT_HELLO +}; +use crate::{ + server::{ServerEvents, UdpServer, IsMessageOfType}, + config::ConfigTable, util::log_error +}; pub fn authenticate_players( - mut server: UniqueViewMut, + mut server: NonSendSync>, events: UniqueView, config: UniqueView ) { for event in &events.0 { - if let ServerEvent::MessageReceived { - from, - message: ClientToServerMessage::ClientHello { - username, - password - } - } = event { - log::info!("ClientHello from {} with username {} and password {:?}", from, username, password); + // if let ServerEvent::MessageReceived { + // from, + // message: ClientToServerMessage::ClientHello { + // username, + // password + // } + // } = event { + + let ServerEvent::Receive(client_addr, data) = event else{ + continue + }; + let Some(client) = server.0.client(client_addr) else { + log::error!("Client doesn't exist"); + continue + }; + if !event.is_message_of_type::() { + continue + } + let Ok(parsed_message) = postcard::from_bytes(data) else { + log::error!("Malformed message 00"); + continue + }; + let ClientToServerMessage::ClientHello { username, password } = parsed_message else { + unreachable!() + }; - // Handle password auth - if let Some(server_password) = &config.server.password { - if let Some(user_password) = &password { - if server_password != user_password { - server.0.send_message(*from, ServerToClientMessage::ServerFuckOff { - reason: "Passwords don't match".into() - }).map_err(log_error).ok(); - continue - } - } else { - server.0.send_message(*from, ServerToClientMessage::ServerFuckOff { - reason: "This server is password-protected".into() - }).map_err(log_error).ok(); + log::info!("ClientHello; username={} password={:?}", username, password); + + // Handle password auth + if let Some(server_password) = &config.server.password { + if let Some(user_password) = &password { + if server_password != user_password { + let res = postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { + reason: "Passwords don't match".into() + }).unwrap().into_boxed_slice(); + client.borrow_mut().send( + res, 0, SendMode::Reliable + ); continue } + } else { + let res = postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { + reason: "This server is password protected".into() + }).unwrap().into_boxed_slice(); + client.borrow_mut().send( + res, 0, SendMode::Reliable + ); + continue } - - //Spawn the user - //TODO Spawn the user on server side - - //Approve the user - server.0.send_message(*from, ServerToClientMessage::ServerHello { - init: InitData { - users: vec![] //TODO create init data - } - }).map_err(log_error).ok(); } + + //Spawn the user + //TODO Spawn the user on server side + + //Approve the user + let res = postcard::to_allocvec(&ServerToClientMessage::ServerHello { + init: InitData { + users: vec![] //TODO create init data + } + }).unwrap().into_boxed_slice(); + client.borrow_mut().send( + res, 0, SendMode::Reliable + ); } } diff --git a/kubi-server/src/main.rs b/kubi-server/src/main.rs index a99dbf0..ad24e18 100644 --- a/kubi-server/src/main.rs +++ b/kubi-server/src/main.rs @@ -5,19 +5,19 @@ pub(crate) mod util; pub(crate) mod config; pub(crate) mod server; pub(crate) mod client; -pub(crate) mod world; +//pub(crate) mod world; pub(crate) mod auth; use config::read_config; use server::{bind_server, update_server, log_server_errors}; use auth::authenticate_players; -use world::{update_world, init_world}; +//use world::{update_world, init_world}; fn initialize() -> Workload { ( read_config, bind_server, - init_world, + //init_world, ).into_workload() } @@ -27,7 +27,7 @@ fn update() -> Workload { ( log_server_errors, authenticate_players, - update_world, + //update_world, ).into_workload() ).into_sequential_workload() } From 45c9b20edecda13a77df36fb022e977bc7ed999f Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 21:13:50 +0100 Subject: [PATCH 155/160] add log --- kubi-server/src/auth.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs index 13b3507..303f6fd 100644 --- a/kubi-server/src/auth.rs +++ b/kubi-server/src/auth.rs @@ -80,5 +80,7 @@ pub fn authenticate_players( client.borrow_mut().send( res, 0, SendMode::Reliable ); + + log::info!("{username} joined the game!") } } From 51f113d162b23115c1a817fe0fd9487c7a6b42e4 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 22:21:19 +0100 Subject: [PATCH 156/160] actually check the event type (facepalm) --- kubi-server/src/auth.rs | 8 ++++---- kubi/src/networking.rs | 26 ++++++++++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/kubi-server/src/auth.rs b/kubi-server/src/auth.rs index 303f6fd..7d6dfae 100644 --- a/kubi-server/src/auth.rs +++ b/kubi-server/src/auth.rs @@ -1,4 +1,4 @@ -use shipyard::{UniqueView, UniqueViewMut, NonSendSync}; +use shipyard::{UniqueView, NonSendSync}; use uflow::{server::Event as ServerEvent, SendMode}; use kubi_shared::networking::messages::{ ClientToServerMessage, @@ -8,11 +8,11 @@ use kubi_shared::networking::messages::{ }; use crate::{ server::{ServerEvents, UdpServer, IsMessageOfType}, - config::ConfigTable, util::log_error + config::ConfigTable }; pub fn authenticate_players( - mut server: NonSendSync>, + server: NonSendSync>, events: UniqueView, config: UniqueView ) { @@ -36,7 +36,7 @@ pub fn authenticate_players( continue } let Ok(parsed_message) = postcard::from_bytes(data) else { - log::error!("Malformed message 00"); + log::error!("Malformed message"); continue }; let ClientToServerMessage::ClientHello { username, password } = parsed_message else { diff --git a/kubi/src/networking.rs b/kubi/src/networking.rs index 04462b6..31450ac 100644 --- a/kubi/src/networking.rs +++ b/kubi/src/networking.rs @@ -3,7 +3,7 @@ use glium::glutin::event_loop::ControlFlow; use std::net::SocketAddr; use uflow::client::{Client, Config as ClientConfig, Event as ClientEvent}; use kubi_shared::networking::{ - messages::{ClientToServerMessage, ServerToClientMessage}, + messages::{ClientToServerMessage, ServerToClientMessage, S_SERVER_HELLO}, state::ClientJoinState }; use crate::{events::EventComponent, control_flow::SetControlFlow}; @@ -87,13 +87,23 @@ fn check_server_hello_response( mut join_state: UniqueViewMut ) { for event in network_events.iter() { - if let ClientEvent::Receive(data) = &event.0 { - - log::info!("Joined the server!"); - //TODO handle init data - *join_state = ClientJoinState::Joined; - return; + let ClientEvent::Receive(data) = &event.0 else { + continue + }; + if !event.is_message_of_type::() { + continue } + let Ok(parsed_message) = postcard::from_bytes(data) else { + log::error!("Malformed message"); + continue + }; + let ServerToClientMessage::ServerHello { init } = parsed_message else { + unreachable!() + }; + //TODO handle init data + *join_state = ClientJoinState::Joined; + log::info!("Joined the server!"); + return; } } @@ -119,7 +129,7 @@ pub fn disconnect_on_exit( if client.0.is_active() { client.0.flush(); client.0.disconnect(); - while client.0.is_active() { client.0.step(); } + while client.0.is_active() { client.0.step().for_each(|_|()); } log::info!("Client disconnected"); } else { log::info!("Client inactive") From 3103b3647d8fd2ad19071f7cc106960938b9be19 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 22:34:41 +0100 Subject: [PATCH 157/160] some big changes --- kubi-shared/src/lib.rs | 1 + kubi-shared/src/player.rs | 4 ++++ kubi/src/main.rs | 15 ++++++++++----- kubi/src/player.rs | 8 +++----- kubi/src/world/mesh/builder.rs | 2 +- 5 files changed, 19 insertions(+), 11 deletions(-) create mode 100644 kubi-shared/src/player.rs diff --git a/kubi-shared/src/lib.rs b/kubi-shared/src/lib.rs index 79f16a7..10ea49c 100644 --- a/kubi-shared/src/lib.rs +++ b/kubi-shared/src/lib.rs @@ -4,4 +4,5 @@ pub mod worldgen; pub mod chunk; pub mod transform; pub mod entity; +pub mod player; pub mod queue; diff --git a/kubi-shared/src/player.rs b/kubi-shared/src/player.rs new file mode 100644 index 0000000..d2df58c --- /dev/null +++ b/kubi-shared/src/player.rs @@ -0,0 +1,4 @@ +use shipyard::Component; + +#[derive(Component)] +pub struct Player; diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 76481e5..cee099f 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -7,7 +7,8 @@ use shipyard::{ World, Workload, IntoWorkload, UniqueView, UniqueViewMut, - NonSendSync, WorkloadModificator, SystemModificator + NonSendSync, WorkloadModificator, + SystemModificator }; use glium::{ glutin::{ @@ -46,9 +47,9 @@ use world::{ loading::update_loaded_world_around_player, raycast::update_raycasts, queue::apply_queued_blocks, - tasks::inject_network_responses_into_manager_queue + tasks::inject_network_responses_into_manager_queue, ChunkStorage }; -use player::spawn_player; +use player::{spawn_player, MainPlayer}; use prefabs::load_prefabs; use settings::load_settings; use camera::compute_cameras; @@ -96,8 +97,8 @@ fn startup() -> Workload { lock_cursor_now, init_input, init_gui, - init_game_world, - spawn_player, + + insert_control_flow_unique, init_delta_time, ).into_workload() @@ -107,6 +108,10 @@ fn update() -> Workload { update_window_size, update_cursor_lock_state, process_inputs, + ( + init_game_world.run_if_missing_unique::(), + spawn_player.run_if_storage_empty::(), + ).into_workload().run_if(is_ingame_or_loading), ( update_networking, inject_network_responses_into_manager_queue, diff --git a/kubi/src/player.rs b/kubi/src/player.rs index cc1e705..0ae0a9a 100644 --- a/kubi/src/player.rs +++ b/kubi/src/player.rs @@ -1,4 +1,4 @@ -use shipyard::{Component, AllStoragesViewMut}; +use shipyard::{Component, AllStoragesViewMut, View, IntoIter}; use crate::{ transform::Transform, camera::Camera, @@ -6,9 +6,7 @@ use crate::{ world::raycast::LookingAtBlock, block_placement::PlayerHolding, }; - -#[derive(Component)] -pub struct Player; +pub use kubi_shared::player::Player; #[derive(Component)] pub struct MainPlayer; @@ -17,7 +15,7 @@ pub fn spawn_player ( mut storages: AllStoragesViewMut ) { log::info!("spawning player"); - storages.add_entity(( + let entity_id = storages.add_entity(( Player, MainPlayer, Transform::default(), diff --git a/kubi/src/world/mesh/builder.rs b/kubi/src/world/mesh/builder.rs index ed1ffd7..fb5949e 100644 --- a/kubi/src/world/mesh/builder.rs +++ b/kubi/src/world/mesh/builder.rs @@ -126,7 +126,7 @@ impl MeshBuilder { let face_type = face_type as usize; let vertices = CROSS_FACES[face_type]; let normal_front = CROSS_FACE_NORMALS[face_type].to_array(); - let normal_back = CROSS_FACE_NORMALS[face_type].to_array(); + let normal_back = CROSS_FACE_NORMALS_BACK[face_type].to_array(); self.vertex_buffer.reserve(8); for i in 0..4 { //push front vertices self.vertex_buffer.push(ChunkVertex { From 02d322474093220df42a528189b141c07fa95716 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 22:53:30 +0100 Subject: [PATCH 158/160] doesn't work? --- kubi/src/main.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/kubi/src/main.rs b/kubi/src/main.rs index cee099f..624e3e0 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -47,7 +47,7 @@ use world::{ loading::update_loaded_world_around_player, raycast::update_raycasts, queue::apply_queued_blocks, - tasks::inject_network_responses_into_manager_queue, ChunkStorage + tasks::{inject_network_responses_into_manager_queue, ChunkTaskManager}, ChunkStorage }; use player::{spawn_player, MainPlayer}; use prefabs::load_prefabs; @@ -97,8 +97,6 @@ fn startup() -> Workload { lock_cursor_now, init_input, init_gui, - - insert_control_flow_unique, init_delta_time, ).into_workload() @@ -109,22 +107,22 @@ fn update() -> Workload { update_cursor_lock_state, process_inputs, ( - init_game_world.run_if_missing_unique::(), + init_game_world.run_if_missing_unique::(), spawn_player.run_if_storage_empty::(), - ).into_workload().run_if(is_ingame_or_loading), + ).into_sequential_workload().run_if(is_ingame_or_loading).tag("game_init"), ( update_networking, - inject_network_responses_into_manager_queue, - ).into_sequential_workload().run_if(is_multiplayer), + inject_network_responses_into_manager_queue.run_if(is_ingame_or_loading), + ).into_sequential_workload().run_if(is_multiplayer).tag("networking").after_all("game_init"), ( switch_to_loading_if_connected - ).into_workload().run_if(is_connecting), + ).into_workload().run_if(is_connecting).after_all("networking"), ( update_loading_screen, - ).into_workload().run_if(is_loading), + ).into_workload().run_if(is_loading).after_all("game_init"), ( update_loaded_world_around_player, - ).into_workload().run_if(is_ingame_or_loading), + ).into_workload().run_if(is_ingame_or_loading).after_all("game_init"), ( update_controllers, generate_move_events, From 2189d114c7cc166e9b7a4a1c985d662e56827a7e Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Wed, 8 Mar 2023 23:00:24 +0100 Subject: [PATCH 159/160] wtf --- kubi/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kubi/src/main.rs b/kubi/src/main.rs index 624e3e0..75503a0 100644 --- a/kubi/src/main.rs +++ b/kubi/src/main.rs @@ -112,7 +112,7 @@ fn update() -> Workload { ).into_sequential_workload().run_if(is_ingame_or_loading).tag("game_init"), ( update_networking, - inject_network_responses_into_manager_queue.run_if(is_ingame_or_loading), + inject_network_responses_into_manager_queue.run_if(is_ingame_or_loading).skip_if_missing_unique::(), ).into_sequential_workload().run_if(is_multiplayer).tag("networking").after_all("game_init"), ( switch_to_loading_if_connected From 0cb066b02bb6920aba14c50229575dc9e6b82374 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 9 Mar 2023 00:31:19 +0100 Subject: [PATCH 160/160] Disable `parallel` feature by default, recalc camera matrix --- kubi-shared/Cargo.toml | 2 +- kubi/Cargo.toml | 3 ++- kubi/src/camera/matrices.rs | 21 ++++++++++++++------- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index 90617c0..a63255d 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] glam = { version = "0.23", features = ["debug-glam-assert", "fast-math", "serde"] } -shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66" } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66", default-features = false, features = ["std"] } strum = { version = "0.24", features = ["derive"] } postcard = { version = "1.0", features = ["alloc"] } serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] } diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 743daf8..f2ca9d0 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -14,7 +14,7 @@ image = { version = "0.24", default_features = false, features = ["png"] } strum = { version = "0.24", features = ["derive"] } hashbrown = "0.13" rayon = "1.6" -shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66", features = ["thread_local"] } +shipyard = { git = "https://github.com/leudz/shipyard", rev = "eb189f66", default-features = false, features = ["std", "proc", "thread_local"] } nohash-hasher = "0.2.0" anyhow = "1.0" flume = "0.10" @@ -27,4 +27,5 @@ winapi = { version = "0.3" } [features] default = [] +parallel = ["shipyard/parallel"] nightly = ["glam/core-simd", "kubi-shared/nightly"] diff --git a/kubi/src/camera/matrices.rs b/kubi/src/camera/matrices.rs index 109c3de..b6ded27 100644 --- a/kubi/src/camera/matrices.rs +++ b/kubi/src/camera/matrices.rs @@ -1,6 +1,6 @@ use glam::{Vec3, Mat4}; -use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track}; -use crate::{transform::Transform, events::WindowResizedEvent}; +use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track, UniqueView, SystemModificator}; +use crate::{transform::Transform, rendering::WindowSize, events::WindowResizedEvent}; use super::Camera; //maybe parallelize these two? @@ -18,11 +18,8 @@ fn update_view_matrix( fn update_perspective_matrix( mut vm_camera: ViewMut, - resize: View, + size: UniqueView, ) { - let Some(&size) = resize.iter().next() else { - return - }; for mut camera in (&mut vm_camera).iter() { camera.perspective_matrix = Mat4::perspective_rh_gl( camera.fov, @@ -33,9 +30,19 @@ fn update_perspective_matrix( } } +fn need_perspective_calc( + v_camera: View, + resize_event: View, +) -> bool { + (resize_event.len() > 0) || + (v_camera.iter().any(|camera| { + camera.perspective_matrix == Mat4::default() + })) +} + pub fn update_matrices() -> Workload { ( update_view_matrix, - update_perspective_matrix, + update_perspective_matrix.run_if(need_perspective_calc), ).into_workload() }