From a6bfc2e5eafe68b78d746901c22af427f691a36a Mon Sep 17 00:00:00 2001 From: theaddon Date: Tue, 12 Nov 2024 10:22:56 +0100 Subject: [PATCH 1/2] Add server crate --- Cargo.toml | 8 +- crates/server/Cargo.toml | 23 +++ crates/server/src/ecs/components/connected.rs | 8 + crates/server/src/ecs/components/damage.rs | 6 + crates/server/src/ecs/components/health.rs | 8 + crates/server/src/ecs/components/mod.rs | 5 + crates/server/src/ecs/components/position.rs | 5 + crates/server/src/ecs/components/velocity.rs | 5 + crates/server/src/ecs/mod.rs | 2 + crates/server/src/ecs/systems/death.rs | 5 + crates/server/src/ecs/systems/mod.rs | 1 + crates/server/src/error.rs | 20 +++ crates/server/src/lib.rs | 6 + crates/server/src/login/handler.rs | 3 + crates/server/src/login/login/add_actor.rs | 55 +++++++ crates/server/src/login/login/handshake.rs | 15 ++ crates/server/src/login/login/login.rs | 35 ++++ crates/server/src/login/login/mod.rs | 50 ++++++ .../src/login/login/network_settings.rs | 60 +++++++ crates/server/src/login/login/packs.rs | 149 +++++++++++++++++ crates/server/src/login/login/play_status.rs | 31 ++++ .../src/login/login/provider/default.rs | 42 +++++ crates/server/src/login/login/provider/mod.rs | 8 + .../server/src/login/login/provider/packs.rs | 16 ++ .../src/login/login/provider/provider.rs | 63 ++++++++ .../server/src/login/login/provider/status.rs | 9 ++ crates/server/src/login/login/set_title.rs | 31 ++++ crates/server/src/login/login/start_game.rs | 152 ++++++++++++++++++ crates/server/src/login/mod.rs | 15 ++ crates/server/src/server/builder.rs | 69 ++++++++ crates/server/src/server/mod.rs | 38 +++++ examples/proto/server.rs | 14 +- 32 files changed, 948 insertions(+), 9 deletions(-) create mode 100644 crates/server/Cargo.toml create mode 100644 crates/server/src/ecs/components/connected.rs create mode 100644 crates/server/src/ecs/components/damage.rs create mode 100644 crates/server/src/ecs/components/health.rs create mode 100644 crates/server/src/ecs/components/mod.rs create mode 100644 crates/server/src/ecs/components/position.rs create mode 100644 crates/server/src/ecs/components/velocity.rs create mode 100644 crates/server/src/ecs/mod.rs create mode 100644 crates/server/src/ecs/systems/death.rs create mode 100644 crates/server/src/ecs/systems/mod.rs create mode 100644 crates/server/src/error.rs create mode 100644 crates/server/src/lib.rs create mode 100644 crates/server/src/login/handler.rs create mode 100644 crates/server/src/login/login/add_actor.rs create mode 100644 crates/server/src/login/login/handshake.rs create mode 100644 crates/server/src/login/login/login.rs create mode 100644 crates/server/src/login/login/mod.rs create mode 100644 crates/server/src/login/login/network_settings.rs create mode 100644 crates/server/src/login/login/packs.rs create mode 100644 crates/server/src/login/login/play_status.rs create mode 100644 crates/server/src/login/login/provider/default.rs create mode 100644 crates/server/src/login/login/provider/mod.rs create mode 100644 crates/server/src/login/login/provider/packs.rs create mode 100644 crates/server/src/login/login/provider/provider.rs create mode 100644 crates/server/src/login/login/provider/status.rs create mode 100644 crates/server/src/login/login/set_title.rs create mode 100644 crates/server/src/login/login/start_game.rs create mode 100644 crates/server/src/login/mod.rs create mode 100644 crates/server/src/server/builder.rs create mode 100644 crates/server/src/server/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 9988a01e..2fcb1e4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,9 @@ bedrockrs_shared = { path = "crates/shared" } bedrockrs_proto = { path = "crates/proto", optional = true } bedrockrs_proto_core = { path = "crates/proto_core", optional = true } + +bedrockrs_server = { path = "crates/server", optional = true } + bedrockrs_macros = { path = "crates/macros", optional = true } bedrockrs_addon = { path = "crates/addon", optional = true } @@ -27,10 +30,11 @@ tokio = { version = "1.40", features = ["full"] } nbtx = { git = "https://github.com/bedrock-crustaceans/nbtx" } [features] -full = ["addon", "proto", "world"] +full = ["addons", "world", "proto", "server"] -addon = ["dep:bedrockrs_addon"] +addons = ["dep:bedrockrs_addon"] proto = ["dep:bedrockrs_proto", "dep:bedrockrs_proto_core", "dep:bedrockrs_macros"] +server = ["dep:bedrockrs_server"] world = ["dep:bedrockrs_world", "dep:bedrockrs_paletted_storage"] [[example]] diff --git a/crates/server/Cargo.toml b/crates/server/Cargo.toml new file mode 100644 index 00000000..8e0bdaea --- /dev/null +++ b/crates/server/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "bedrockrs_server" +version = "0.1.0" +edition = "2021" + +[dependencies] +thiserror = "2.0" + +bedrockrs_core = { path = "../core" } +bedrockrs_shared = { path = "../shared" } +bedrockrs_proto = { path = "../proto" } + +tokio = { version = "1.40", features = ["full", "tracing"] } +shipyard = { version = "0.7", features = ["parallel", "proc", "rayon", "tracing"]} +rayon = "1.10" +vek = "0.17" + +xuid = "1.0" + +[features] +scoreboard = [] +forms = [] +visibility = [] diff --git a/crates/server/src/ecs/components/connected.rs b/crates/server/src/ecs/components/connected.rs new file mode 100644 index 00000000..00440c82 --- /dev/null +++ b/crates/server/src/ecs/components/connected.rs @@ -0,0 +1,8 @@ +use shipyard::Component; +use bedrockrs_proto::connection::shard::arc::ConnectionShared; +use bedrockrs_proto::helper::ProtoHelper; + +#[derive(Component)] +pub struct Connected where ::GamePacketType: Sync { + pub connection: ConnectionShared, +} diff --git a/crates/server/src/ecs/components/damage.rs b/crates/server/src/ecs/components/damage.rs new file mode 100644 index 00000000..42ab4d12 --- /dev/null +++ b/crates/server/src/ecs/components/damage.rs @@ -0,0 +1,6 @@ +use shipyard::Component; + +#[derive(Component)] +pub struct Damage { + pub damage: f32, +} diff --git a/crates/server/src/ecs/components/health.rs b/crates/server/src/ecs/components/health.rs new file mode 100644 index 00000000..d73da8ba --- /dev/null +++ b/crates/server/src/ecs/components/health.rs @@ -0,0 +1,8 @@ +use shipyard::Component; + +#[derive(Component)] +pub struct Health { + pub current: f32, + pub min: f32, + pub max: f32, +} diff --git a/crates/server/src/ecs/components/mod.rs b/crates/server/src/ecs/components/mod.rs new file mode 100644 index 00000000..27172945 --- /dev/null +++ b/crates/server/src/ecs/components/mod.rs @@ -0,0 +1,5 @@ +pub mod connected; +pub mod position; +pub mod velocity; +mod health; +mod damage; diff --git a/crates/server/src/ecs/components/position.rs b/crates/server/src/ecs/components/position.rs new file mode 100644 index 00000000..b761062b --- /dev/null +++ b/crates/server/src/ecs/components/position.rs @@ -0,0 +1,5 @@ +use shipyard::Component; +use vek::Vec3; + +#[derive(Component)] +pub struct Pos(pub Vec3); diff --git a/crates/server/src/ecs/components/velocity.rs b/crates/server/src/ecs/components/velocity.rs new file mode 100644 index 00000000..61303a2d --- /dev/null +++ b/crates/server/src/ecs/components/velocity.rs @@ -0,0 +1,5 @@ +use shipyard::Component; +use vek::Vec3; + +#[derive(Component)] +pub struct Vel(pub Vec3); diff --git a/crates/server/src/ecs/mod.rs b/crates/server/src/ecs/mod.rs new file mode 100644 index 00000000..621600aa --- /dev/null +++ b/crates/server/src/ecs/mod.rs @@ -0,0 +1,2 @@ +pub mod components; +pub mod systems; diff --git a/crates/server/src/ecs/systems/death.rs b/crates/server/src/ecs/systems/death.rs new file mode 100644 index 00000000..d3c211d1 --- /dev/null +++ b/crates/server/src/ecs/systems/death.rs @@ -0,0 +1,5 @@ +use shipyard::World; + +pub fn death() { + +} diff --git a/crates/server/src/ecs/systems/mod.rs b/crates/server/src/ecs/systems/mod.rs new file mode 100644 index 00000000..2ea13551 --- /dev/null +++ b/crates/server/src/ecs/systems/mod.rs @@ -0,0 +1 @@ +pub mod death; diff --git a/crates/server/src/error.rs b/crates/server/src/error.rs new file mode 100644 index 00000000..a5620ed8 --- /dev/null +++ b/crates/server/src/error.rs @@ -0,0 +1,20 @@ +use std::error::Error; +use thiserror::Error; +use bedrockrs_proto::error::ConnectionError; + +pub enum StartError { + +} + +#[derive(Error, Debug)] +pub enum LoginError { + #[error("Connection Error: {0}")] + ConnectionError(#[from] ConnectionError), + #[error("Login aborted, reason: {reason}")] + Abort { reason: String }, + #[error("Wrong protocol version (client: {client}, server: {server:?})")] + WrongProtocolVersion { client: i32, server: Vec }, + #[error("Format Error: {0}")] + FormatError(String), +} + diff --git a/crates/server/src/lib.rs b/crates/server/src/lib.rs new file mode 100644 index 00000000..6e591d59 --- /dev/null +++ b/crates/server/src/lib.rs @@ -0,0 +1,6 @@ +pub mod server; +pub mod login; +pub mod error; +pub mod entity; +mod components; +mod ecs; diff --git a/crates/server/src/login/handler.rs b/crates/server/src/login/handler.rs new file mode 100644 index 00000000..7fb22c0b --- /dev/null +++ b/crates/server/src/login/handler.rs @@ -0,0 +1,3 @@ +pub trait LoginHandler { + +} diff --git a/crates/server/src/login/login/add_actor.rs b/crates/server/src/login/login/add_actor.rs new file mode 100644 index 00000000..da805907 --- /dev/null +++ b/crates/server/src/login/login/add_actor.rs @@ -0,0 +1,55 @@ +use bedrockrs_core::{Vec2, Vec3}; +use bedrockrs_shared::{actor_runtime_id::ActorRuntimeID, actor_unique_id::ActorUniqueID}; + +use crate::{ + connection::ConnectionShard, + error::LoginError, + gamepackets::GamePackets, + packets::add_actor::AddActorPacket, + types::{ + actor_type::ActorType, + property_sync_data::{FloatEntriesList, IntEntriesList, PropertySyncData}, + }, +}; + +use super::provider::LoginProvider; + +pub async fn add_actor( + conn: &mut ConnectionShard, + provider: &mut impl LoginProvider, +) -> Result<(), LoginError> { + ////////////////////////////////////// + // todo: AddActorPacket + ////////////////////////////////////// + + let add_actor = AddActorPacket { + target_actor_id: ActorUniqueID(610), + target_runtime_id: ActorRuntimeID(403), + actor_type: ActorType::Pig.to_string(), + position: Vec3 { + x: 4.0, + y: 8.0, + z: 7.0, + }, + velocity: Vec3 { + x: 4.0, + y: 8.0, + z: 7.0, + }, + rotation: Vec2 { x: 270.0, y: 90.0 }, + y_head_rotation: 45.0, + y_body_rotation: 90.0, + attributes: vec![], + actor_data: vec![], + synced_properties: PropertySyncData { + int: IntEntriesList { entries: vec![] }, + float: FloatEntriesList { entries: vec![] }, + }, + actor_links: vec![], + }; + + conn.send(GamePackets::AddEntity(add_actor)).await?; + conn.flush().await?; + + Ok(()) +} diff --git a/crates/server/src/login/login/handshake.rs b/crates/server/src/login/login/handshake.rs new file mode 100644 index 00000000..227385df --- /dev/null +++ b/crates/server/src/login/login/handshake.rs @@ -0,0 +1,15 @@ +use crate::connection::ConnectionShard; +use crate::error::LoginError; +use crate::login::provider::{LoginProvider, LoginProviderStatus}; + +pub async fn handshake( + conn: &mut ConnectionShard, + provider: &mut impl LoginProvider, +) -> LoginProviderStatus { + + if !provider.encryption_enabled() { + return Ok(()); + }; + + todo!("impl the handshake") +} diff --git a/crates/server/src/login/login/login.rs b/crates/server/src/login/login/login.rs new file mode 100644 index 00000000..146200f0 --- /dev/null +++ b/crates/server/src/login/login/login.rs @@ -0,0 +1,35 @@ +use crate::connection::ConnectionShard; +use crate::error::LoginError; +use crate::gamepackets::GamePackets; +use crate::login::provider::{LoginProvider, LoginProviderStatus}; + +pub async fn login( + conn: &mut ConnectionShard, + provider: &mut impl LoginProvider, +) -> LoginProviderStatus { + ////////////////////////////////////// + // Login Packet + ////////////////////////////////////// + + let mut login = match conn.recv().await? { + GamePackets::Login(pk) => pk, + other => { + return Err(LoginError::FormatError(format!( + "Expected Login packet, got: {other:?}" + ))) + } + }; + + match provider.on_login_pk(&mut login) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason } => { + return Err(LoginError::Abort { reason }); + } + }; + + if provider.auth_enabled() { + todo!("impl xbox auth with data from login pk") + }; + + Ok(()) +} diff --git a/crates/server/src/login/login/mod.rs b/crates/server/src/login/login/mod.rs new file mode 100644 index 00000000..bacc86a8 --- /dev/null +++ b/crates/server/src/login/login/mod.rs @@ -0,0 +1,50 @@ +use bedrockrs_proto::connection::Connection; +use crate::connection::ConnectionShard; +use crate::error::LoginError; +use crate::login::handshake::handshake; +use crate::login::login::login; +use crate::login::login::provider::LoginProvider; +use crate::login::network_settings::network_settings; +use crate::login::packs::packs; +use crate::login::play_status::play_status_login; +use crate::login::provider::LoginProvider; +use crate::login::start_game::start_game; + +mod add_actor; +mod handshake; +mod login; +mod network_settings; +mod packs; +mod play_status; +pub mod provider; +mod set_title; +mod start_game; + +macro_rules! handle_login_status { + ($provider:ident, $handler:ident, $packet:ident) => { + match $provider.$handler(&mut $packet) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason, disconnect_reason } => { + return Err(LoginError::Abort { reason }); + } + }; + }; +} + +pub async fn login_sequence( + conn: &mut Connection, + mut provider: impl LoginProvider, +) -> Result<(), LoginError> { + network_settings(conn, &mut provider).await?; + + login(conn, &mut provider).await?; + play_status_login(conn, &mut provider).await?; + + handshake(conn, &mut provider).await?; + + packs(conn, &mut provider).await?; + + start_game(conn, &mut provider).await?; + + Ok(()) +} diff --git a/crates/server/src/login/login/network_settings.rs b/crates/server/src/login/login/network_settings.rs new file mode 100644 index 00000000..5a70ce92 --- /dev/null +++ b/crates/server/src/login/login/network_settings.rs @@ -0,0 +1,60 @@ +use crate::connection::ConnectionShard; +use crate::error::LoginError; +use crate::gamepackets::GamePackets; +use crate::login::provider::{LoginProvider, LoginProviderStatus}; +use crate::packets::network_settings::NetworkSettingsPacket; + +pub async fn network_settings( + conn: &mut ConnectionShard, + provider: &mut impl LoginProvider, +) -> LoginProviderStatus { + ////////////////////////////////////// + // Network Settings Request Packet + ////////////////////////////////////// + + let mut network_settings_request = match conn.recv().await? { + GamePackets::NetworkSettingsRequest(pk) => pk, + other => { + return Err(LoginError::FormatError(format!( + "Expected RequestNetworkSettings packet, got: {other:?}" + ))) + } + }; + + match provider.on_network_settings_request_pk(&mut network_settings_request) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason } => { + return Err(LoginError::Abort { reason }); + } + }; + + ////////////////////////////////////// + // Network Settings Packet + ////////////////////////////////////// + + let compression = provider.compression(); + + let mut network_settings = NetworkSettingsPacket { + compression_threshold: compression.threshold(), + compression_algorithm: compression.id_u16(), + // TODO What do these 3 fields do? + client_throttle_enabled: false, + client_throttle_threshold: 0, + client_throttle_scalar: 0.0, + }; + + match provider.on_network_settings_pk(&mut network_settings) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason } => { + return Err(LoginError::Abort { reason }); + } + }; + + conn.send(GamePackets::NetworkSettings(network_settings)) + .await?; + conn.flush().await?; + + conn.set_compression(Some(compression)).await?; + + Ok(()) +} diff --git a/crates/server/src/login/login/packs.rs b/crates/server/src/login/login/packs.rs new file mode 100644 index 00000000..f88fafe8 --- /dev/null +++ b/crates/server/src/login/login/packs.rs @@ -0,0 +1,149 @@ +use crate::connection::ConnectionShard; +use crate::error::LoginError; +use crate::gamepackets::GamePackets; +use crate::login::provider::packs::LoginProviderPacks; +use crate::login::provider::{LoginProvider, LoginProviderStatus}; +use crate::packets::resource_packs_info::ResourcePacksInfoPacket; +use crate::packets::resource_packs_stack::ResourcePacksStackPacket; +use crate::types::base_game_version::BaseGameVersion; +use crate::types::experiments::Experiments; + +pub async fn packs( + conn: &mut ConnectionShard, + provider: &mut impl LoginProvider, +) -> LoginProviderStatus { + match provider.packs() { + LoginProviderPacks::CDN { + behavior_packs, + resource_packs, + cdn_urls, + } => { + ////////////////////////////////////// + // Resource Packs Info Packet + ////////////////////////////////////// + + // TODO impl this + let mut resource_packs_info = ResourcePacksInfoPacket { + resource_pack_required: false, + has_addon_packs: false, + has_scripts: false, + force_server_packs_enabled: false, + behavior_packs: vec![], + resource_packs: vec![], + cdn_urls: cdn_urls.clone(), + }; + + match provider.on_resource_packs_info_pk(&mut resource_packs_info) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason } => { + return Err(LoginError::Abort { reason }); + } + }; + + conn.send(GamePackets::ResourcePacksInfo(resource_packs_info)) + .await?; + conn.flush().await?; + + ////////////////////////////////////// + // Resource Pack Client Response + // (/Client Cache Status Packet) + ////////////////////////////////////// + + match conn.recv().await? { + GamePackets::ClientCacheStatus(mut client_cache_status) => { + match provider.on_client_cache_status_pk(&mut client_cache_status) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason } => { + return Err(LoginError::Abort { reason }); + } + }; + + conn.set_cache_supported(client_cache_status.cache_supported).await?; + + match conn.recv().await? { + GamePackets::ResourcePackClientResponse(mut resource_pack_client_response) => { + match provider.on_resource_packs_response_pk(&mut resource_pack_client_response) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason } => { + return Err(LoginError::Abort { reason }); + } + }; + } + other => { + return Err(LoginError::FormatError(format!( + "Expected ClientCacheStatus or ResourcePackClientResponse packet, got: {other:?}" + ))) + } + } + } + GamePackets::ResourcePackClientResponse(mut resource_pack_client_response) => { + match provider.on_resource_packs_response_pk(&mut resource_pack_client_response) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason } => { + return Err(LoginError::Abort { reason }); + } + }; + } + other => { + return Err(LoginError::FormatError(format!( + "Expected ClientCacheStatus or ResourcePackClientResponse packet, got: {other:?}" + ))) + } + } + + ////////////////////////////////////// + // Resource Packs Stack Packet + ////////////////////////////////////// + + // TODO impl this + let mut resource_packs_stack = ResourcePacksStackPacket { + texture_pack_required: false, + addons: vec![], + texture_packs: vec![], + base_game_version: BaseGameVersion(String::from("1.0")), + experiments: Experiments { + experiments: vec![], + ever_toggled: false, + }, + include_editor_packs: false, + }; + + match provider.on_resource_packs_stack_pk(&mut resource_packs_stack) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason } => { + return Err(LoginError::Abort { reason }); + } + }; + + conn.send(GamePackets::ResourcePackStack(resource_packs_stack)) + .await?; + conn.flush().await?; + + ////////////////////////////////////// + // Resource Pack Client Response + ////////////////////////////////////// + + match conn.recv().await? { + GamePackets::ResourcePackClientResponse(mut resource_pack_client_response) => { + match provider.on_resource_packs_response_pk(&mut resource_pack_client_response) + { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason } => { + return Err(LoginError::Abort { reason }); + } + }; + } + other => { + return Err(LoginError::FormatError(format!( + "Expected ResourcePackClientResponse packet, got: {other:?}" + ))) + } + } + } + LoginProviderPacks::DirectNetworkTransfer { .. } => { + todo!("impl LoginProvider bedrockrs::DirectNetworkTransfer in login process") + } + }; + + Ok(()) +} diff --git a/crates/server/src/login/login/play_status.rs b/crates/server/src/login/login/play_status.rs new file mode 100644 index 00000000..923d5959 --- /dev/null +++ b/crates/server/src/login/login/play_status.rs @@ -0,0 +1,31 @@ +use crate::connection::ConnectionShard; +use crate::error::LoginError; +use crate::gamepackets::GamePackets; +use crate::login::provider::{LoginProvider, LoginProviderStatus}; +use crate::packets::play_status::PlayStatusPacket; +use crate::types::play_status::PlayStatusType; + +pub async fn play_status_login( + conn: &mut ConnectionShard, + provider: &mut impl LoginProvider, +) -> LoginProviderStatus { + ////////////////////////////////////// + // Play Status Packet (Login) + ////////////////////////////////////// + + let mut play_status = PlayStatusPacket { + status: PlayStatusType::LoginSuccess, + }; + + match provider.on_play_status_pk(&mut play_status) { + LoginProviderStatus::ContinueLogin => {} + LoginProviderStatus::AbortLogin { reason, disconnect_reason } => { + return Err(LoginError::Abort { reason }); + } + }; + + conn.send(GamePackets::PlayStatus(play_status)).await?; + conn.flush().await?; + + Ok(()) +} diff --git a/crates/server/src/login/login/provider/default.rs b/crates/server/src/login/login/provider/default.rs new file mode 100644 index 00000000..fbfcf802 --- /dev/null +++ b/crates/server/src/login/login/provider/default.rs @@ -0,0 +1,42 @@ +use crate::compression::Compression; +use crate::login::provider::packs::LoginProviderPacks; +use crate::login::provider::LoginProvider; + +pub struct DefaultLoginProvider { + packs: LoginProviderPacks, +} + +impl DefaultLoginProvider { + pub fn new() -> Self { + Self { + packs: LoginProviderPacks::CDN { + behavior_packs: vec![], + resource_packs: vec![], + cdn_urls: vec![], + }, + } + } +} + +impl Default for DefaultLoginProvider { + fn default() -> Self { + Self::new() + } +} + +impl LoginProvider for DefaultLoginProvider { + fn compression(&self) -> Compression { + Compression::None + } + fn encryption_enabled(&self) -> bool { + false + } + + fn auth_enabled(&self) -> bool { + false + } + + fn packs(&self) -> &LoginProviderPacks { + &self.packs + } +} diff --git a/crates/server/src/login/login/provider/mod.rs b/crates/server/src/login/login/provider/mod.rs new file mode 100644 index 00000000..f32e8e9e --- /dev/null +++ b/crates/server/src/login/login/provider/mod.rs @@ -0,0 +1,8 @@ +pub use default::*; +pub use provider::*; +pub use status::*; + +pub mod default; +pub mod packs; +pub mod provider; +pub mod status; diff --git a/crates/server/src/login/login/provider/packs.rs b/crates/server/src/login/login/provider/packs.rs new file mode 100644 index 00000000..081f7c2c --- /dev/null +++ b/crates/server/src/login/login/provider/packs.rs @@ -0,0 +1,16 @@ +use bedrockrs_addon::behavior::BehaviorPack; +use bedrockrs_addon::resource::ResourcePack; + +use crate::types::pack_url::PackURL; + +pub enum LoginProviderPacks { + CDN { + behavior_packs: Vec, + resource_packs: Vec, + cdn_urls: Vec, + }, + DirectNetworkTransfer { + behavior_packs: Vec, + resource_packs: Vec, + }, +} diff --git a/crates/server/src/login/login/provider/provider.rs b/crates/server/src/login/login/provider/provider.rs new file mode 100644 index 00000000..77fbf1a2 --- /dev/null +++ b/crates/server/src/login/login/provider/provider.rs @@ -0,0 +1,63 @@ +use crate::compression::Compression; +use crate::login::provider::packs::LoginProviderPacks; +use crate::login::provider::status::LoginProviderStatus; +use crate::packets::client_cache_status::ClientCacheStatusPacket; +use crate::packets::login::LoginPacket; +use crate::packets::network_settings::NetworkSettingsPacket; +use crate::packets::network_settings_request::NetworkSettingsRequestPacket; +use crate::packets::play_status::PlayStatusPacket; +use crate::packets::resource_packs_info::ResourcePacksInfoPacket; +use crate::packets::resource_packs_response::ResourcePacksResponsePacket; +use crate::packets::resource_packs_stack::ResourcePacksStackPacket; + +pub trait LoginProvider { + fn compression(&self) -> Compression; + fn encryption_enabled(&self) -> bool; + fn auth_enabled(&self) -> bool; + + fn packs(&self) -> &LoginProviderPacks; + + fn on_network_settings_request_pk( + &mut self, + _pk: &mut NetworkSettingsRequestPacket, + ) -> LoginProviderStatus { + LoginProviderStatus::ContinueLogin + } + + fn on_network_settings_pk(&mut self, _pk: &mut NetworkSettingsPacket) -> LoginProviderStatus { + LoginProviderStatus::ContinueLogin + } + + fn on_login_pk(&mut self, _pk: &mut LoginPacket) -> LoginProviderStatus { + LoginProviderStatus::ContinueLogin + } + + fn on_play_status_pk(&mut self, _pk: &mut PlayStatusPacket) -> LoginProviderStatus { + LoginProviderStatus::ContinueLogin + } + + fn on_resource_packs_info_pk( + &mut self, + _pk: &mut ResourcePacksInfoPacket, + ) -> LoginProviderStatus { + LoginProviderStatus::ContinueLogin + } + + fn on_resource_packs_stack_pk( + &mut self, + _pk: &mut ResourcePacksStackPacket, + ) -> LoginProviderStatus { + LoginProviderStatus::ContinueLogin + } + + fn on_resource_packs_response_pk( + &mut self, + _pk: &mut ResourcePacksResponsePacket, + ) -> LoginProviderStatus { + LoginProviderStatus::ContinueLogin + } + + fn on_client_cache_status_pk(&self, _pk: &mut ClientCacheStatusPacket) -> LoginProviderStatus { + LoginProviderStatus::ContinueLogin + } +} diff --git a/crates/server/src/login/login/provider/status.rs b/crates/server/src/login/login/provider/status.rs new file mode 100644 index 00000000..dd65514d --- /dev/null +++ b/crates/server/src/login/login/provider/status.rs @@ -0,0 +1,9 @@ +use crate::types::disconnect_reason::DisconnectReason; + +pub enum LoginProviderStatus { + ContinueLogin, + AbortLogin { + reason: String, + disconnect_reason: Option, + }, +} diff --git a/crates/server/src/login/login/set_title.rs b/crates/server/src/login/login/set_title.rs new file mode 100644 index 00000000..bb4e58b2 --- /dev/null +++ b/crates/server/src/login/login/set_title.rs @@ -0,0 +1,31 @@ +use crate::connection::ConnectionShard; +use crate::error::LoginError; +use crate::gamepackets::GamePackets; +use crate::login::provider::LoginProvider; +use crate::packets::set_title::SetTitlePacket; +use crate::types::title_type::TitleType; +use xuid::Xuid; + +pub async fn set_title( + conn: &mut ConnectionShard, + provider: &mut impl LoginProvider, +) -> Result<(), LoginError> { + ////////////////////////////////////// + // Set Title + ////////////////////////////////////// + + let set_title = SetTitlePacket { + title_type: TitleType::Title, + title_text: String::from("hello_text"), + fade_in_time: 500, + stay_time: 500, + fade_out_time: 500, + xuid: Xuid::from(123456789), + platform_online_id: String::from("hello_platform_online_id"), + }; + + conn.send(GamePackets::SetTitle(set_title)).await?; + conn.flush().await?; + + Ok(()) +} diff --git a/crates/server/src/login/login/start_game.rs b/crates/server/src/login/login/start_game.rs new file mode 100644 index 00000000..149d6e2d --- /dev/null +++ b/crates/server/src/login/login/start_game.rs @@ -0,0 +1,152 @@ +use bedrockrs_core::{Vec2, Vec3}; +use std::collections::HashMap; +use uuid::Uuid; + +use bedrockrs_shared::actor_runtime_id::ActorRuntimeID; +use bedrockrs_shared::actor_unique_id::ActorUniqueID; +use bedrockrs_shared::world::difficulty::Difficulty; +use bedrockrs_shared::world::dimension::Dimension; +use bedrockrs_shared::world::gamemode::Gamemode; +use bedrockrs_shared::world::generator_type::GeneratorType; + +use crate::connection::ConnectionShard; +use crate::error::LoginError; +use crate::gamepackets::GamePackets; +use crate::login::provider::{LoginProvider, LoginProviderStatus}; +use crate::packets::play_status::PlayStatusPacket; +use crate::packets::start_game::StartGamePacket; +use crate::types::base_game_version::BaseGameVersion; +use crate::types::block_pos::BlockPos; +use crate::types::chat_restriction_level::ChatRestrictionLevel; +use crate::types::edu_shared_uri_resource::EduSharedResourceUri; +use crate::types::experiments::Experiments; +use crate::types::level_settings::LevelSettings; +use crate::types::network_permissions::NetworkPermissions; +use crate::types::play_status::PlayStatusType; +use crate::types::player_movement_mode::PlayerMovementMode; +use crate::types::player_movement_settings::PlayerMovementSettings; +use crate::types::spawn_biome_type::SpawnBiomeType; +use crate::types::spawn_settings::SpawnSettings; +use bedrockrs_shared::world::editor_world_type::EditorWorldType; + +pub async fn start_game( + conn: &mut ConnectionShard, + provider: &mut impl LoginProvider, +) -> Result { + ////////////////////////////////////// + // Start Game Packet + ////////////////////////////////////// + + let start_game = StartGamePacket { + target_actor_id: ActorUniqueID(609), + target_runtime_id: ActorRuntimeID(402), + gamemode: Gamemode::Creative, + position: Vec3 { + x: 4.0, + y: 6.0, + z: 7.0, + }, + rotation: Vec2 { x: 270.0, y: 90.0 }, + settings: LevelSettings { + seed: 777777777777, + spawn_settings: SpawnSettings { + biome_type: SpawnBiomeType::Default, + user_defined_biome_name: String::from("RandomBiome"), + dimension: Dimension::Overworld, + }, + generator_type: GeneratorType::Overworld, + gamemode: Gamemode::Creative, + hardcore: false, + difficulty: Difficulty::Peaceful, + default_spawn_block: BlockPos { + x: 100, + y: 200, + z: 300, + }, + achievements_disabled: true, + editor_world_type: EditorWorldType::NotEditor, + created_in_editor: false, + exported_from_editor: false, + day_cycle_stop_time: 2000, + education_edition_offer: 0, + education_features: false, + education_product_id: String::from(""), + rain_level: 300.0, + lightning_level: 400.0, + platform_locked_content: false, + multiplayer_intended: true, + lan_broadcasting_intended: true, + broadcasting_settings_xbox_live: 2, + broadcasting_settings_platform: 2, + commands_enabled: true, + texture_pack_required: false, + gamerules: vec![], + experiments: Experiments { + experiments: vec![], + ever_toggled: false, + }, + bonus_chest: false, + start_with_map: false, + player_permission: 3, + server_chunk_tick_radius: 4, + locked_behavior_packs: false, + locked_resource_packs: false, + from_locked_template: false, + msa_gamertags_only: false, + from_template: false, + is_template_locked_settings: false, + only_spawn_v1_villagers: false, + persona_disabled: false, + custom_skins_disabled: false, + emote_chat_muted: false, + base_game_version: BaseGameVersion(String::from("1.21.0")), + limited_world_width: 0, + limited_world_depth: 0, + new_nether: true, + edu_shared_uri_resource: EduSharedResourceUri { + button_name: String::from(""), + link_uri: String::from(""), + }, + force_experimental_gameplay: true, + chat_restriction_level: ChatRestrictionLevel::None, + disable_player_interactions: false, + server_id: String::from(""), + world_id: String::from(""), + scenario_id: String::from(""), + }, + level_id: String::from("UmFuZG9tIFdvcmxk"), + level_name: String::from("Random World"), + template_content_identity: String::new(), + trial: false, + movement_settings: PlayerMovementSettings { + authority_mode: PlayerMovementMode::Client, + rewind_history_size: 3200, + server_authoritative_block_breaking: false, + }, + current_level_time: 9000, + enchantment_seed: 99000, + blocks: vec![], + items: vec![], + multiplayer_correlation_id: String::from("c5d3d2cc-27fd-4221-9de6-d22c4d423d53"), + enable_item_stack_net_manager: false, + server_version: String::from("1.19.2"), + player_property_data: nbtx::Value::Compound(HashMap::new()), + block_type_registry_checksum: 0, + world_template_id: Uuid::nil(), + enable_clientside_world_generation: false, + use_block_network_id_hashes: true, + network_permission: NetworkPermissions { + server_auth_sound_enabled: false, + }, + }; + + conn.send(GamePackets::StartGame(start_game)).await?; + conn.send(GamePackets::PlayStatus(PlayStatusPacket { + status: PlayStatusType::PlayerSpawn, + })) + .await?; + + conn.flush().await?; + + Ok(()) +} diff --git a/crates/server/src/login/mod.rs b/crates/server/src/login/mod.rs new file mode 100644 index 00000000..41ff81f1 --- /dev/null +++ b/crates/server/src/login/mod.rs @@ -0,0 +1,15 @@ +mod handler; +mod login; + +use bedrockrs_proto::connection::Connection; +use shipyard::World; +use bedrockrs_proto::connection::shard::arc::{ConnectionShared, shard}; +use bedrockrs_proto::version::v729::helper::ProtoHelperV729; +use crate::error::LoginError; +use crate::login::handler::LoginHandler; + +pub async fn login(connection: Connection, world: &mut World, login_handler: impl LoginHandler) -> Result<(), LoginError> { + let mut shard = shard::(connection); + + todo!() +} \ No newline at end of file diff --git a/crates/server/src/server/builder.rs b/crates/server/src/server/builder.rs new file mode 100644 index 00000000..825a5108 --- /dev/null +++ b/crates/server/src/server/builder.rs @@ -0,0 +1,69 @@ +use crate::server::Server; +use bedrockrs_proto::listener::Listener; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + +pub struct ServerBuilder { + name: String, + sub_name: String, + listeners_info: Vec, + max_player: u32, +} + +impl ServerBuilder { + pub fn new() -> ServerBuilder { + Self::default() + } + + pub fn name(mut self, name: &str) -> ServerBuilder { + self.name = name.to_owned(); + self + } + + pub fn sub_name(mut self, sub_name: &str) -> ServerBuilder { + self.sub_name = sub_name.to_owned(); + self + } + + pub fn listener(mut self, addr: SocketAddr) -> ServerBuilder { + self.listeners_info.push(addr); + self + } + + pub async fn build(mut self) -> Server { + if self.listeners_info.is_empty() { + self.listeners_info.push(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 0)), 19132)); + } + + let mut listeners = Vec::with_capacity(self.listeners_info.len()); + + for addr in self.listeners_info { + listeners.push(Listener::new_raknet( + self.name.clone(), + self.sub_name.clone(), + String::from("1.21.0"), + self.max_player, + 0, + addr, + false, + ).await.unwrap()) + }; + + Server { + listeners, + name: self.name, + sub_name: self.sub_name, + world: Default::default(), + } + } +} + +impl Default for ServerBuilder { + fn default() -> Self { + Self { + name: "bedrock-server".to_string(), + sub_name: "bedrock-rs".to_string(), + listeners_info: vec![], + max_player: 100, + } + } +} diff --git a/crates/server/src/server/mod.rs b/crates/server/src/server/mod.rs new file mode 100644 index 00000000..5c612ed4 --- /dev/null +++ b/crates/server/src/server/mod.rs @@ -0,0 +1,38 @@ +use std::error::Error; +use bedrockrs_proto::listener::Listener; +use shipyard::World; +use crate::entity::Entity; +use crate::entity::player::Player; +use crate::entity::position::Pos; +use crate::entity::velocity::Vel; +use crate::error::LoginError; +use crate::login::login; + +pub mod builder; + +pub struct Server { + listeners: Vec, + name: String, + sub_name: String, + pub world: World, +} + +impl Server { + pub async fn start(&mut self) { + for listener in &mut self.listeners { + listener.start().await.unwrap(); + } + + self.world.run_default_workload().unwrap() + } + + pub async fn stop(&mut self) { + for listener in &mut self.listeners { + listener.stop().await.expect("TODO: panic message"); + } + } + + pub async fn accept(&mut self) -> Result<(), LoginError> { + todo!() + } +} diff --git a/examples/proto/server.rs b/examples/proto/server.rs index d128d401..c3447078 100644 --- a/examples/proto/server.rs +++ b/examples/proto/server.rs @@ -46,7 +46,7 @@ async fn main() { "1.0".to_string(), 100, 10, - SocketAddr::V4(SocketAddrV4::from_str("127.0.0.1:19132").unwrap()), + "127.0.0.1:19132".parse().unwrap(), false, ) .await @@ -124,12 +124,12 @@ async fn handle_login(mut conn: Connection) { println!("{:#?}", conn.recv::().await.unwrap()); println!("ResourcePackClientResponse"); - conn.send::(&[GamePackets::DisconnectPlayer(DisconnectPlayerPacket { - reason: DisconnectReason::Unknown, - message: Some(String::from("IDK")), - })]) - .await - .unwrap(); + // conn.send::(&[GamePackets::DisconnectPlayer(DisconnectPlayerPacket { + // reason: DisconnectReason::Unknown, + // message: Some(String::from("IDK")), + // })]) + // .await + // .unwrap(); // let packet1 = StartGamePacket { // target_actor_id: ActorUniqueID(609), From 9c91474b312162dfcfb91c27b5be50bcde9da8ce Mon Sep 17 00:00:00 2001 From: theaddon Date: Tue, 12 Nov 2024 10:24:17 +0100 Subject: [PATCH 2/2] Adapt for functionality --- crates/server/src/lib.rs | 4 +- crates/server/src/login/login/add_actor.rs | 55 ------- crates/server/src/login/login/handshake.rs | 15 -- crates/server/src/login/login/login.rs | 35 ---- crates/server/src/login/login/mod.rs | 50 ------ .../src/login/login/network_settings.rs | 60 ------- crates/server/src/login/login/packs.rs | 149 ----------------- crates/server/src/login/login/play_status.rs | 31 ---- .../src/login/login/provider/default.rs | 42 ----- crates/server/src/login/login/provider/mod.rs | 8 - .../server/src/login/login/provider/packs.rs | 16 -- .../src/login/login/provider/provider.rs | 63 -------- .../server/src/login/login/provider/status.rs | 9 -- crates/server/src/login/login/set_title.rs | 31 ---- crates/server/src/login/login/start_game.rs | 152 ------------------ crates/server/src/login/mod.rs | 3 +- crates/server/src/server/mod.rs | 4 - 17 files changed, 2 insertions(+), 725 deletions(-) delete mode 100644 crates/server/src/login/login/add_actor.rs delete mode 100644 crates/server/src/login/login/handshake.rs delete mode 100644 crates/server/src/login/login/login.rs delete mode 100644 crates/server/src/login/login/mod.rs delete mode 100644 crates/server/src/login/login/network_settings.rs delete mode 100644 crates/server/src/login/login/packs.rs delete mode 100644 crates/server/src/login/login/play_status.rs delete mode 100644 crates/server/src/login/login/provider/default.rs delete mode 100644 crates/server/src/login/login/provider/mod.rs delete mode 100644 crates/server/src/login/login/provider/packs.rs delete mode 100644 crates/server/src/login/login/provider/provider.rs delete mode 100644 crates/server/src/login/login/provider/status.rs delete mode 100644 crates/server/src/login/login/set_title.rs delete mode 100644 crates/server/src/login/login/start_game.rs diff --git a/crates/server/src/lib.rs b/crates/server/src/lib.rs index 6e591d59..2646c136 100644 --- a/crates/server/src/lib.rs +++ b/crates/server/src/lib.rs @@ -1,6 +1,4 @@ pub mod server; pub mod login; pub mod error; -pub mod entity; -mod components; -mod ecs; +pub mod ecs; diff --git a/crates/server/src/login/login/add_actor.rs b/crates/server/src/login/login/add_actor.rs deleted file mode 100644 index da805907..00000000 --- a/crates/server/src/login/login/add_actor.rs +++ /dev/null @@ -1,55 +0,0 @@ -use bedrockrs_core::{Vec2, Vec3}; -use bedrockrs_shared::{actor_runtime_id::ActorRuntimeID, actor_unique_id::ActorUniqueID}; - -use crate::{ - connection::ConnectionShard, - error::LoginError, - gamepackets::GamePackets, - packets::add_actor::AddActorPacket, - types::{ - actor_type::ActorType, - property_sync_data::{FloatEntriesList, IntEntriesList, PropertySyncData}, - }, -}; - -use super::provider::LoginProvider; - -pub async fn add_actor( - conn: &mut ConnectionShard, - provider: &mut impl LoginProvider, -) -> Result<(), LoginError> { - ////////////////////////////////////// - // todo: AddActorPacket - ////////////////////////////////////// - - let add_actor = AddActorPacket { - target_actor_id: ActorUniqueID(610), - target_runtime_id: ActorRuntimeID(403), - actor_type: ActorType::Pig.to_string(), - position: Vec3 { - x: 4.0, - y: 8.0, - z: 7.0, - }, - velocity: Vec3 { - x: 4.0, - y: 8.0, - z: 7.0, - }, - rotation: Vec2 { x: 270.0, y: 90.0 }, - y_head_rotation: 45.0, - y_body_rotation: 90.0, - attributes: vec![], - actor_data: vec![], - synced_properties: PropertySyncData { - int: IntEntriesList { entries: vec![] }, - float: FloatEntriesList { entries: vec![] }, - }, - actor_links: vec![], - }; - - conn.send(GamePackets::AddEntity(add_actor)).await?; - conn.flush().await?; - - Ok(()) -} diff --git a/crates/server/src/login/login/handshake.rs b/crates/server/src/login/login/handshake.rs deleted file mode 100644 index 227385df..00000000 --- a/crates/server/src/login/login/handshake.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::connection::ConnectionShard; -use crate::error::LoginError; -use crate::login::provider::{LoginProvider, LoginProviderStatus}; - -pub async fn handshake( - conn: &mut ConnectionShard, - provider: &mut impl LoginProvider, -) -> LoginProviderStatus { - - if !provider.encryption_enabled() { - return Ok(()); - }; - - todo!("impl the handshake") -} diff --git a/crates/server/src/login/login/login.rs b/crates/server/src/login/login/login.rs deleted file mode 100644 index 146200f0..00000000 --- a/crates/server/src/login/login/login.rs +++ /dev/null @@ -1,35 +0,0 @@ -use crate::connection::ConnectionShard; -use crate::error::LoginError; -use crate::gamepackets::GamePackets; -use crate::login::provider::{LoginProvider, LoginProviderStatus}; - -pub async fn login( - conn: &mut ConnectionShard, - provider: &mut impl LoginProvider, -) -> LoginProviderStatus { - ////////////////////////////////////// - // Login Packet - ////////////////////////////////////// - - let mut login = match conn.recv().await? { - GamePackets::Login(pk) => pk, - other => { - return Err(LoginError::FormatError(format!( - "Expected Login packet, got: {other:?}" - ))) - } - }; - - match provider.on_login_pk(&mut login) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason } => { - return Err(LoginError::Abort { reason }); - } - }; - - if provider.auth_enabled() { - todo!("impl xbox auth with data from login pk") - }; - - Ok(()) -} diff --git a/crates/server/src/login/login/mod.rs b/crates/server/src/login/login/mod.rs deleted file mode 100644 index bacc86a8..00000000 --- a/crates/server/src/login/login/mod.rs +++ /dev/null @@ -1,50 +0,0 @@ -use bedrockrs_proto::connection::Connection; -use crate::connection::ConnectionShard; -use crate::error::LoginError; -use crate::login::handshake::handshake; -use crate::login::login::login; -use crate::login::login::provider::LoginProvider; -use crate::login::network_settings::network_settings; -use crate::login::packs::packs; -use crate::login::play_status::play_status_login; -use crate::login::provider::LoginProvider; -use crate::login::start_game::start_game; - -mod add_actor; -mod handshake; -mod login; -mod network_settings; -mod packs; -mod play_status; -pub mod provider; -mod set_title; -mod start_game; - -macro_rules! handle_login_status { - ($provider:ident, $handler:ident, $packet:ident) => { - match $provider.$handler(&mut $packet) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason, disconnect_reason } => { - return Err(LoginError::Abort { reason }); - } - }; - }; -} - -pub async fn login_sequence( - conn: &mut Connection, - mut provider: impl LoginProvider, -) -> Result<(), LoginError> { - network_settings(conn, &mut provider).await?; - - login(conn, &mut provider).await?; - play_status_login(conn, &mut provider).await?; - - handshake(conn, &mut provider).await?; - - packs(conn, &mut provider).await?; - - start_game(conn, &mut provider).await?; - - Ok(()) -} diff --git a/crates/server/src/login/login/network_settings.rs b/crates/server/src/login/login/network_settings.rs deleted file mode 100644 index 5a70ce92..00000000 --- a/crates/server/src/login/login/network_settings.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::connection::ConnectionShard; -use crate::error::LoginError; -use crate::gamepackets::GamePackets; -use crate::login::provider::{LoginProvider, LoginProviderStatus}; -use crate::packets::network_settings::NetworkSettingsPacket; - -pub async fn network_settings( - conn: &mut ConnectionShard, - provider: &mut impl LoginProvider, -) -> LoginProviderStatus { - ////////////////////////////////////// - // Network Settings Request Packet - ////////////////////////////////////// - - let mut network_settings_request = match conn.recv().await? { - GamePackets::NetworkSettingsRequest(pk) => pk, - other => { - return Err(LoginError::FormatError(format!( - "Expected RequestNetworkSettings packet, got: {other:?}" - ))) - } - }; - - match provider.on_network_settings_request_pk(&mut network_settings_request) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason } => { - return Err(LoginError::Abort { reason }); - } - }; - - ////////////////////////////////////// - // Network Settings Packet - ////////////////////////////////////// - - let compression = provider.compression(); - - let mut network_settings = NetworkSettingsPacket { - compression_threshold: compression.threshold(), - compression_algorithm: compression.id_u16(), - // TODO What do these 3 fields do? - client_throttle_enabled: false, - client_throttle_threshold: 0, - client_throttle_scalar: 0.0, - }; - - match provider.on_network_settings_pk(&mut network_settings) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason } => { - return Err(LoginError::Abort { reason }); - } - }; - - conn.send(GamePackets::NetworkSettings(network_settings)) - .await?; - conn.flush().await?; - - conn.set_compression(Some(compression)).await?; - - Ok(()) -} diff --git a/crates/server/src/login/login/packs.rs b/crates/server/src/login/login/packs.rs deleted file mode 100644 index f88fafe8..00000000 --- a/crates/server/src/login/login/packs.rs +++ /dev/null @@ -1,149 +0,0 @@ -use crate::connection::ConnectionShard; -use crate::error::LoginError; -use crate::gamepackets::GamePackets; -use crate::login::provider::packs::LoginProviderPacks; -use crate::login::provider::{LoginProvider, LoginProviderStatus}; -use crate::packets::resource_packs_info::ResourcePacksInfoPacket; -use crate::packets::resource_packs_stack::ResourcePacksStackPacket; -use crate::types::base_game_version::BaseGameVersion; -use crate::types::experiments::Experiments; - -pub async fn packs( - conn: &mut ConnectionShard, - provider: &mut impl LoginProvider, -) -> LoginProviderStatus { - match provider.packs() { - LoginProviderPacks::CDN { - behavior_packs, - resource_packs, - cdn_urls, - } => { - ////////////////////////////////////// - // Resource Packs Info Packet - ////////////////////////////////////// - - // TODO impl this - let mut resource_packs_info = ResourcePacksInfoPacket { - resource_pack_required: false, - has_addon_packs: false, - has_scripts: false, - force_server_packs_enabled: false, - behavior_packs: vec![], - resource_packs: vec![], - cdn_urls: cdn_urls.clone(), - }; - - match provider.on_resource_packs_info_pk(&mut resource_packs_info) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason } => { - return Err(LoginError::Abort { reason }); - } - }; - - conn.send(GamePackets::ResourcePacksInfo(resource_packs_info)) - .await?; - conn.flush().await?; - - ////////////////////////////////////// - // Resource Pack Client Response - // (/Client Cache Status Packet) - ////////////////////////////////////// - - match conn.recv().await? { - GamePackets::ClientCacheStatus(mut client_cache_status) => { - match provider.on_client_cache_status_pk(&mut client_cache_status) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason } => { - return Err(LoginError::Abort { reason }); - } - }; - - conn.set_cache_supported(client_cache_status.cache_supported).await?; - - match conn.recv().await? { - GamePackets::ResourcePackClientResponse(mut resource_pack_client_response) => { - match provider.on_resource_packs_response_pk(&mut resource_pack_client_response) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason } => { - return Err(LoginError::Abort { reason }); - } - }; - } - other => { - return Err(LoginError::FormatError(format!( - "Expected ClientCacheStatus or ResourcePackClientResponse packet, got: {other:?}" - ))) - } - } - } - GamePackets::ResourcePackClientResponse(mut resource_pack_client_response) => { - match provider.on_resource_packs_response_pk(&mut resource_pack_client_response) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason } => { - return Err(LoginError::Abort { reason }); - } - }; - } - other => { - return Err(LoginError::FormatError(format!( - "Expected ClientCacheStatus or ResourcePackClientResponse packet, got: {other:?}" - ))) - } - } - - ////////////////////////////////////// - // Resource Packs Stack Packet - ////////////////////////////////////// - - // TODO impl this - let mut resource_packs_stack = ResourcePacksStackPacket { - texture_pack_required: false, - addons: vec![], - texture_packs: vec![], - base_game_version: BaseGameVersion(String::from("1.0")), - experiments: Experiments { - experiments: vec![], - ever_toggled: false, - }, - include_editor_packs: false, - }; - - match provider.on_resource_packs_stack_pk(&mut resource_packs_stack) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason } => { - return Err(LoginError::Abort { reason }); - } - }; - - conn.send(GamePackets::ResourcePackStack(resource_packs_stack)) - .await?; - conn.flush().await?; - - ////////////////////////////////////// - // Resource Pack Client Response - ////////////////////////////////////// - - match conn.recv().await? { - GamePackets::ResourcePackClientResponse(mut resource_pack_client_response) => { - match provider.on_resource_packs_response_pk(&mut resource_pack_client_response) - { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason } => { - return Err(LoginError::Abort { reason }); - } - }; - } - other => { - return Err(LoginError::FormatError(format!( - "Expected ResourcePackClientResponse packet, got: {other:?}" - ))) - } - } - } - LoginProviderPacks::DirectNetworkTransfer { .. } => { - todo!("impl LoginProvider bedrockrs::DirectNetworkTransfer in login process") - } - }; - - Ok(()) -} diff --git a/crates/server/src/login/login/play_status.rs b/crates/server/src/login/login/play_status.rs deleted file mode 100644 index 923d5959..00000000 --- a/crates/server/src/login/login/play_status.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::connection::ConnectionShard; -use crate::error::LoginError; -use crate::gamepackets::GamePackets; -use crate::login::provider::{LoginProvider, LoginProviderStatus}; -use crate::packets::play_status::PlayStatusPacket; -use crate::types::play_status::PlayStatusType; - -pub async fn play_status_login( - conn: &mut ConnectionShard, - provider: &mut impl LoginProvider, -) -> LoginProviderStatus { - ////////////////////////////////////// - // Play Status Packet (Login) - ////////////////////////////////////// - - let mut play_status = PlayStatusPacket { - status: PlayStatusType::LoginSuccess, - }; - - match provider.on_play_status_pk(&mut play_status) { - LoginProviderStatus::ContinueLogin => {} - LoginProviderStatus::AbortLogin { reason, disconnect_reason } => { - return Err(LoginError::Abort { reason }); - } - }; - - conn.send(GamePackets::PlayStatus(play_status)).await?; - conn.flush().await?; - - Ok(()) -} diff --git a/crates/server/src/login/login/provider/default.rs b/crates/server/src/login/login/provider/default.rs deleted file mode 100644 index fbfcf802..00000000 --- a/crates/server/src/login/login/provider/default.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::compression::Compression; -use crate::login::provider::packs::LoginProviderPacks; -use crate::login::provider::LoginProvider; - -pub struct DefaultLoginProvider { - packs: LoginProviderPacks, -} - -impl DefaultLoginProvider { - pub fn new() -> Self { - Self { - packs: LoginProviderPacks::CDN { - behavior_packs: vec![], - resource_packs: vec![], - cdn_urls: vec![], - }, - } - } -} - -impl Default for DefaultLoginProvider { - fn default() -> Self { - Self::new() - } -} - -impl LoginProvider for DefaultLoginProvider { - fn compression(&self) -> Compression { - Compression::None - } - fn encryption_enabled(&self) -> bool { - false - } - - fn auth_enabled(&self) -> bool { - false - } - - fn packs(&self) -> &LoginProviderPacks { - &self.packs - } -} diff --git a/crates/server/src/login/login/provider/mod.rs b/crates/server/src/login/login/provider/mod.rs deleted file mode 100644 index f32e8e9e..00000000 --- a/crates/server/src/login/login/provider/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub use default::*; -pub use provider::*; -pub use status::*; - -pub mod default; -pub mod packs; -pub mod provider; -pub mod status; diff --git a/crates/server/src/login/login/provider/packs.rs b/crates/server/src/login/login/provider/packs.rs deleted file mode 100644 index 081f7c2c..00000000 --- a/crates/server/src/login/login/provider/packs.rs +++ /dev/null @@ -1,16 +0,0 @@ -use bedrockrs_addon::behavior::BehaviorPack; -use bedrockrs_addon::resource::ResourcePack; - -use crate::types::pack_url::PackURL; - -pub enum LoginProviderPacks { - CDN { - behavior_packs: Vec, - resource_packs: Vec, - cdn_urls: Vec, - }, - DirectNetworkTransfer { - behavior_packs: Vec, - resource_packs: Vec, - }, -} diff --git a/crates/server/src/login/login/provider/provider.rs b/crates/server/src/login/login/provider/provider.rs deleted file mode 100644 index 77fbf1a2..00000000 --- a/crates/server/src/login/login/provider/provider.rs +++ /dev/null @@ -1,63 +0,0 @@ -use crate::compression::Compression; -use crate::login::provider::packs::LoginProviderPacks; -use crate::login::provider::status::LoginProviderStatus; -use crate::packets::client_cache_status::ClientCacheStatusPacket; -use crate::packets::login::LoginPacket; -use crate::packets::network_settings::NetworkSettingsPacket; -use crate::packets::network_settings_request::NetworkSettingsRequestPacket; -use crate::packets::play_status::PlayStatusPacket; -use crate::packets::resource_packs_info::ResourcePacksInfoPacket; -use crate::packets::resource_packs_response::ResourcePacksResponsePacket; -use crate::packets::resource_packs_stack::ResourcePacksStackPacket; - -pub trait LoginProvider { - fn compression(&self) -> Compression; - fn encryption_enabled(&self) -> bool; - fn auth_enabled(&self) -> bool; - - fn packs(&self) -> &LoginProviderPacks; - - fn on_network_settings_request_pk( - &mut self, - _pk: &mut NetworkSettingsRequestPacket, - ) -> LoginProviderStatus { - LoginProviderStatus::ContinueLogin - } - - fn on_network_settings_pk(&mut self, _pk: &mut NetworkSettingsPacket) -> LoginProviderStatus { - LoginProviderStatus::ContinueLogin - } - - fn on_login_pk(&mut self, _pk: &mut LoginPacket) -> LoginProviderStatus { - LoginProviderStatus::ContinueLogin - } - - fn on_play_status_pk(&mut self, _pk: &mut PlayStatusPacket) -> LoginProviderStatus { - LoginProviderStatus::ContinueLogin - } - - fn on_resource_packs_info_pk( - &mut self, - _pk: &mut ResourcePacksInfoPacket, - ) -> LoginProviderStatus { - LoginProviderStatus::ContinueLogin - } - - fn on_resource_packs_stack_pk( - &mut self, - _pk: &mut ResourcePacksStackPacket, - ) -> LoginProviderStatus { - LoginProviderStatus::ContinueLogin - } - - fn on_resource_packs_response_pk( - &mut self, - _pk: &mut ResourcePacksResponsePacket, - ) -> LoginProviderStatus { - LoginProviderStatus::ContinueLogin - } - - fn on_client_cache_status_pk(&self, _pk: &mut ClientCacheStatusPacket) -> LoginProviderStatus { - LoginProviderStatus::ContinueLogin - } -} diff --git a/crates/server/src/login/login/provider/status.rs b/crates/server/src/login/login/provider/status.rs deleted file mode 100644 index dd65514d..00000000 --- a/crates/server/src/login/login/provider/status.rs +++ /dev/null @@ -1,9 +0,0 @@ -use crate::types::disconnect_reason::DisconnectReason; - -pub enum LoginProviderStatus { - ContinueLogin, - AbortLogin { - reason: String, - disconnect_reason: Option, - }, -} diff --git a/crates/server/src/login/login/set_title.rs b/crates/server/src/login/login/set_title.rs deleted file mode 100644 index bb4e58b2..00000000 --- a/crates/server/src/login/login/set_title.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::connection::ConnectionShard; -use crate::error::LoginError; -use crate::gamepackets::GamePackets; -use crate::login::provider::LoginProvider; -use crate::packets::set_title::SetTitlePacket; -use crate::types::title_type::TitleType; -use xuid::Xuid; - -pub async fn set_title( - conn: &mut ConnectionShard, - provider: &mut impl LoginProvider, -) -> Result<(), LoginError> { - ////////////////////////////////////// - // Set Title - ////////////////////////////////////// - - let set_title = SetTitlePacket { - title_type: TitleType::Title, - title_text: String::from("hello_text"), - fade_in_time: 500, - stay_time: 500, - fade_out_time: 500, - xuid: Xuid::from(123456789), - platform_online_id: String::from("hello_platform_online_id"), - }; - - conn.send(GamePackets::SetTitle(set_title)).await?; - conn.flush().await?; - - Ok(()) -} diff --git a/crates/server/src/login/login/start_game.rs b/crates/server/src/login/login/start_game.rs deleted file mode 100644 index 149d6e2d..00000000 --- a/crates/server/src/login/login/start_game.rs +++ /dev/null @@ -1,152 +0,0 @@ -use bedrockrs_core::{Vec2, Vec3}; -use std::collections::HashMap; -use uuid::Uuid; - -use bedrockrs_shared::actor_runtime_id::ActorRuntimeID; -use bedrockrs_shared::actor_unique_id::ActorUniqueID; -use bedrockrs_shared::world::difficulty::Difficulty; -use bedrockrs_shared::world::dimension::Dimension; -use bedrockrs_shared::world::gamemode::Gamemode; -use bedrockrs_shared::world::generator_type::GeneratorType; - -use crate::connection::ConnectionShard; -use crate::error::LoginError; -use crate::gamepackets::GamePackets; -use crate::login::provider::{LoginProvider, LoginProviderStatus}; -use crate::packets::play_status::PlayStatusPacket; -use crate::packets::start_game::StartGamePacket; -use crate::types::base_game_version::BaseGameVersion; -use crate::types::block_pos::BlockPos; -use crate::types::chat_restriction_level::ChatRestrictionLevel; -use crate::types::edu_shared_uri_resource::EduSharedResourceUri; -use crate::types::experiments::Experiments; -use crate::types::level_settings::LevelSettings; -use crate::types::network_permissions::NetworkPermissions; -use crate::types::play_status::PlayStatusType; -use crate::types::player_movement_mode::PlayerMovementMode; -use crate::types::player_movement_settings::PlayerMovementSettings; -use crate::types::spawn_biome_type::SpawnBiomeType; -use crate::types::spawn_settings::SpawnSettings; -use bedrockrs_shared::world::editor_world_type::EditorWorldType; - -pub async fn start_game( - conn: &mut ConnectionShard, - provider: &mut impl LoginProvider, -) -> Result { - ////////////////////////////////////// - // Start Game Packet - ////////////////////////////////////// - - let start_game = StartGamePacket { - target_actor_id: ActorUniqueID(609), - target_runtime_id: ActorRuntimeID(402), - gamemode: Gamemode::Creative, - position: Vec3 { - x: 4.0, - y: 6.0, - z: 7.0, - }, - rotation: Vec2 { x: 270.0, y: 90.0 }, - settings: LevelSettings { - seed: 777777777777, - spawn_settings: SpawnSettings { - biome_type: SpawnBiomeType::Default, - user_defined_biome_name: String::from("RandomBiome"), - dimension: Dimension::Overworld, - }, - generator_type: GeneratorType::Overworld, - gamemode: Gamemode::Creative, - hardcore: false, - difficulty: Difficulty::Peaceful, - default_spawn_block: BlockPos { - x: 100, - y: 200, - z: 300, - }, - achievements_disabled: true, - editor_world_type: EditorWorldType::NotEditor, - created_in_editor: false, - exported_from_editor: false, - day_cycle_stop_time: 2000, - education_edition_offer: 0, - education_features: false, - education_product_id: String::from(""), - rain_level: 300.0, - lightning_level: 400.0, - platform_locked_content: false, - multiplayer_intended: true, - lan_broadcasting_intended: true, - broadcasting_settings_xbox_live: 2, - broadcasting_settings_platform: 2, - commands_enabled: true, - texture_pack_required: false, - gamerules: vec![], - experiments: Experiments { - experiments: vec![], - ever_toggled: false, - }, - bonus_chest: false, - start_with_map: false, - player_permission: 3, - server_chunk_tick_radius: 4, - locked_behavior_packs: false, - locked_resource_packs: false, - from_locked_template: false, - msa_gamertags_only: false, - from_template: false, - is_template_locked_settings: false, - only_spawn_v1_villagers: false, - persona_disabled: false, - custom_skins_disabled: false, - emote_chat_muted: false, - base_game_version: BaseGameVersion(String::from("1.21.0")), - limited_world_width: 0, - limited_world_depth: 0, - new_nether: true, - edu_shared_uri_resource: EduSharedResourceUri { - button_name: String::from(""), - link_uri: String::from(""), - }, - force_experimental_gameplay: true, - chat_restriction_level: ChatRestrictionLevel::None, - disable_player_interactions: false, - server_id: String::from(""), - world_id: String::from(""), - scenario_id: String::from(""), - }, - level_id: String::from("UmFuZG9tIFdvcmxk"), - level_name: String::from("Random World"), - template_content_identity: String::new(), - trial: false, - movement_settings: PlayerMovementSettings { - authority_mode: PlayerMovementMode::Client, - rewind_history_size: 3200, - server_authoritative_block_breaking: false, - }, - current_level_time: 9000, - enchantment_seed: 99000, - blocks: vec![], - items: vec![], - multiplayer_correlation_id: String::from("c5d3d2cc-27fd-4221-9de6-d22c4d423d53"), - enable_item_stack_net_manager: false, - server_version: String::from("1.19.2"), - player_property_data: nbtx::Value::Compound(HashMap::new()), - block_type_registry_checksum: 0, - world_template_id: Uuid::nil(), - enable_clientside_world_generation: false, - use_block_network_id_hashes: true, - network_permission: NetworkPermissions { - server_auth_sound_enabled: false, - }, - }; - - conn.send(GamePackets::StartGame(start_game)).await?; - conn.send(GamePackets::PlayStatus(PlayStatusPacket { - status: PlayStatusType::PlayerSpawn, - })) - .await?; - - conn.flush().await?; - - Ok(()) -} diff --git a/crates/server/src/login/mod.rs b/crates/server/src/login/mod.rs index 41ff81f1..a0a1cbbf 100644 --- a/crates/server/src/login/mod.rs +++ b/crates/server/src/login/mod.rs @@ -1,5 +1,4 @@ mod handler; -mod login; use bedrockrs_proto::connection::Connection; use shipyard::World; @@ -10,6 +9,6 @@ use crate::login::handler::LoginHandler; pub async fn login(connection: Connection, world: &mut World, login_handler: impl LoginHandler) -> Result<(), LoginError> { let mut shard = shard::(connection); - + todo!() } \ No newline at end of file diff --git a/crates/server/src/server/mod.rs b/crates/server/src/server/mod.rs index 5c612ed4..dae271e7 100644 --- a/crates/server/src/server/mod.rs +++ b/crates/server/src/server/mod.rs @@ -1,10 +1,6 @@ use std::error::Error; use bedrockrs_proto::listener::Listener; use shipyard::World; -use crate::entity::Entity; -use crate::entity::player::Player; -use crate::entity::position::Pos; -use crate::entity::velocity::Vel; use crate::error::LoginError; use crate::login::login;