From e54fae7165cfad2269e971159960a03285d9d25a Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Thu, 23 Jan 2025 14:53:34 -0600 Subject: [PATCH] client networking probably working --- Cargo.lock | 4 + crates/client/Cargo.toml | 5 +- crates/client/src/ecs.rs | 7 ++ crates/client/src/lib.rs | 11 +- crates/client/src/networking/mod.rs | 6 + crates/client/src/networking/ws_native.rs | 0 crates/client/src/networking/ws_wasm.rs | 67 ++++++++++++ crates/client/src/rendering/mod.rs | 29 +++-- crates/client/src/rendering/renderer.rs | 28 ++++- crates/common/Cargo.toml | 3 +- crates/common/src/lib.rs | 20 +++- crates/{server => common}/src/packet.rs | 39 ++++--- crates/server/src/main.rs | 2 - crates/server/src/module/component.rs | 29 +---- crates/server/src/module/mod.rs | 71 ++++++------ crates/server/src/module/save.rs | 30 ++--- crates/server/src/module/thruster.rs | 9 +- crates/server/src/planet.rs | 103 ++++++++---------- crates/server/src/player/client_login.rs | 59 +++++----- crates/server/src/player/mod.rs | 15 +-- crates/server/src/player/packet.rs | 18 +-- .../server/src/player/player_mouse_input.rs | 13 ++- crates/server/src/player/request_save.rs | 8 +- crates/server/src/player/send_message.rs | 14 +-- crates/server/src/ws.rs | 22 ++++ 25 files changed, 383 insertions(+), 229 deletions(-) create mode 100644 crates/client/src/networking/mod.rs create mode 100644 crates/client/src/networking/ws_native.rs create mode 100644 crates/client/src/networking/ws_wasm.rs rename crates/{server => common}/src/packet.rs (79%) diff --git a/Cargo.lock b/Cargo.lock index ee15c464ee167d8f869c65255f12a25295840483..0d2be2277c56817b7fe36dd714c19d327cdc0bca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6083,6 +6083,9 @@ dependencies = [ "nalgebra 0.33.2", "pollster", "reqwest", + "serde", + "serde_json", + "starkingdoms-common", "thiserror 2.0.9", "tracing", "tracing-subscriber", @@ -6103,6 +6106,7 @@ dependencies = [ "hmac", "rmp-serde", "serde", + "serde_json", "sha2", ] diff --git a/crates/client/Cargo.toml b/crates/client/Cargo.toml index 87693f069004eb921f2a3da3076dcf9d09ac83f2..84b1e0930fb3ebcad6a912bc4ed269b6487c6da2 100644 --- a/crates/client/Cargo.toml +++ b/crates/client/Cargo.toml @@ -21,13 +21,16 @@ egui-wgpu = "0.30" web-time = "1" futures = "0.3" nalgebra = "0.33" +starkingdoms-common = { version = "0.1", path = "../common" } +serde = "1" +serde_json = "1" # WASM dependencies [target.'cfg(target_arch = "wasm32")'.dependencies] tracing-web = "0.1" # Log output console_error_panic_hook = "0.1" # Give useful information in the panic response, other than the useless "entered unreachable code" wasm-bindgen = "0.2" -web-sys = { version = "0.3", features = ["Window", "Location"] } +web-sys = { version = "0.3", features = ["Window", "Location", "WebSocket", "MessageEvent"] } wasm-bindgen-futures = "0.4" reqwest = "0.11" diff --git a/crates/client/src/ecs.rs b/crates/client/src/ecs.rs index 7f69d2db9c592f5623d048844269fdaeb0c1a7c6..98697409b85cef17aa904a120d42793fc68434e9 100644 --- a/crates/client/src/ecs.rs +++ b/crates/client/src/ecs.rs @@ -1,7 +1,9 @@ use bevy_ecs::bundle::Bundle; use bevy_ecs::component::Component; +use bevy_ecs::event::Event; use bevy_ecs::system::Resource; use nalgebra::Matrix3; +use starkingdoms_common::packet::Packet; #[derive(Component, Debug, Clone, Copy)] pub struct Translation { @@ -85,3 +87,8 @@ pub struct Camera { pub shear_y: f32, pub zoom: f32, } + +#[derive(Event, Clone, PartialEq)] +pub struct SendPacket(pub Packet); +#[derive(Event, Clone, PartialEq)] +pub struct RecvPacket(pub Packet); diff --git a/crates/client/src/lib.rs b/crates/client/src/lib.rs index aef5b864aa84f663e0211b7c8548cf8286d3fc16..4fe2d816c7e65b4c06e27ec8573866377d5f9641 100644 --- a/crates/client/src/lib.rs +++ b/crates/client/src/lib.rs @@ -3,11 +3,13 @@ use crate::input::MouseWheelEvent; use crate::rendering::ui::UiRenderable; use crate::rendering::App; use bevy_ecs::event::{EventReader, Events}; +use bevy_ecs::observer::Trigger; use bevy_ecs::schedule::Schedule; use bevy_ecs::system::ResMut; use bevy_ecs::world::World; -use ecs::Shear; +use ecs::{RecvPacket, SendPacket, Shear}; use egui::{Context, DragValue}; +use networking::ws::Ws; use rendering::assets::Assets; use tracing::info; use winit::event_loop::{ControlFlow, EventLoop}; @@ -22,6 +24,7 @@ pub mod platform; pub mod ecs; pub mod input; pub mod rendering; +pub mod networking; // Hi, you've found the real main function! This is called AFTER platform-specific initialization code. pub fn start() { @@ -47,6 +50,10 @@ pub fn start() { zoom: 1.0, }); world.insert_resource(Assets::new()); + world.insert_resource(Ws::new().expect("Couldn't connect to server")); + + let send_packet_events = Events::::default(); + let recv_packet_events = Events::::default(); let mut start_schedule = Schedule::default(); // Add startup things here @@ -82,7 +89,7 @@ pub fn start() { let event_loop = EventLoop::new().unwrap(); event_loop.set_control_flow(ControlFlow::Poll); event_loop - .run_app(&mut App::new(world, update_schedule, Gui {})) + .run_app(&mut App::new(world, send_packet_events, recv_packet_events, update_schedule, Gui {})) .unwrap(); } diff --git a/crates/client/src/networking/mod.rs b/crates/client/src/networking/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..df5ea3202602c5840202e3db641640a74fc9f50e --- /dev/null +++ b/crates/client/src/networking/mod.rs @@ -0,0 +1,6 @@ +#[cfg(target_arch = "wasm32")] +#[path = "ws_wasm.rs"] +pub mod ws; +#[cfg(not(target_arch = "wasm32"))] +#[path = "ws_native.rs"] +pub mod ws; diff --git a/crates/client/src/networking/ws_native.rs b/crates/client/src/networking/ws_native.rs new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/crates/client/src/networking/ws_wasm.rs b/crates/client/src/networking/ws_wasm.rs new file mode 100644 index 0000000000000000000000000000000000000000..7be42c48bc772333bb1f4f4b5d13273611ccd144 --- /dev/null +++ b/crates/client/src/networking/ws_wasm.rs @@ -0,0 +1,67 @@ +use std::{any::Any, cell::{OnceCell, RefCell}, rc::Rc, sync::{Arc, Mutex, RwLock}}; + +use bevy_ecs::{system::Resource, world::World}; +use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, SinkExt}; +use wasm_bindgen::{prelude::Closure, JsCast, JsValue}; +use wasm_bindgen_futures::spawn_local; +use web_sys::{MessageEvent, WebSocket}; +use starkingdoms_common::packet::Packet; + +use crate::ecs::RecvPacket; + +const PORT: u16 = 3000; + +#[derive(Debug)] +pub struct Socket(WebSocket); +unsafe impl Send for Socket {} +unsafe impl Sync for Socket {} + +#[derive(Resource, Debug)] +pub struct Ws { + socket: Socket, + pub sender: UnboundedSender, + pub receiver: UnboundedReceiver, + packet_receiver: UnboundedReceiver, +} + +impl Ws { + pub fn new() -> Result { + let window = web_sys::window().unwrap(); + let ws = WebSocket::new(&format!("ws://{}:{}", + window.location().hostname().unwrap(), PORT))?; + let (packet_sender, receiver) = unbounded(); + let packet_sender = Rc::new(RwLock::new(packet_sender)); + let (sender, packet_receiver) = unbounded(); + + /*let onopen_callback = Closure::::new(move || { + + }); + ws.set_onopen(Some(onopen_callback.as_ref().unchecked_ref())); + onopen_callback.forget();*/ + let onmessage_callback = Closure::::new(move |e: MessageEvent| { + //tracing::error!("{}", ws.ready_state()); + let data = e.data().as_string().expect("Expected string, found some other type"); + let data: Packet = serde_json::from_str(&data).expect("Received invalid json from server"); + let sender_clone = packet_sender.clone(); + spawn_local(async move { + sender_clone.write().unwrap().send(data).await.expect("Couldn't transmit packet to client"); + }); + }); + ws.set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref())); + onmessage_callback.forget(); + Ok(Ws { + socket: Socket(ws), + sender, + receiver, + packet_receiver, + }) + } + pub fn send_all_packets_from_channel(&mut self) { + while let Ok(Some(packet)) = self.packet_receiver.try_next() { + self.socket.0.send_with_str(&serde_json::to_string(&packet).expect("Couldn't convert packet to json")).expect("Couldn't send packet to server"); + } + } + pub fn send_packet(&mut self, packet: &Packet) { + self.socket.0.send_with_str(&serde_json::to_string(packet).expect("Couldn't convert packet to json")).expect("Couldn't send packet to server"); + } +} diff --git a/crates/client/src/rendering/mod.rs b/crates/client/src/rendering/mod.rs index c802af48f74102e3b3f66d5b9508b38413b2dd03..bd0e10a4fb7e8cfcc2385bada3dbcf4f8fc3bb30 100644 --- a/crates/client/src/rendering/mod.rs +++ b/crates/client/src/rendering/mod.rs @@ -9,11 +9,13 @@ pub mod assets; pub mod assets; pub mod ui; +use crate::ecs::{RecvPacket, SendPacket}; use crate::input::MouseWheelEvent; use crate::rendering::renderer::RenderInitRes::{Initialized, NotReadyYet}; #[allow(unused_imports)] use crate::rendering::renderer::{Renderer, RenderInitRes}; use crate::rendering::ui::UiRenderable; +use bevy_ecs::event::Events; use bevy_ecs::schedule::Schedule; use bevy_ecs::world::World; use std::ops::Add; @@ -38,10 +40,13 @@ pub struct App { world: Option, update_schedule: Option, ui_renderable: Option, + send_packet_events: Option>, + recv_packet_events: Option>, } impl App { - pub fn new(world: World, update_schedule: Schedule, ui_renderable: T) -> Self { + pub fn new(world: World, send_packet_events: Events, + recv_packet_events: Events, update_schedule: Schedule, ui_renderable: T) -> Self { Self { window: None, renderer: None, @@ -50,6 +55,8 @@ impl App { world: Some(world), update_schedule: Some(update_schedule), ui_renderable: Some(ui_renderable), + send_packet_events: Some(send_packet_events), + recv_packet_events: Some(recv_packet_events), } } } @@ -64,20 +71,25 @@ impl ApplicationHandler for App { let world = self.world.take().unwrap(); let update_schedule = self.update_schedule.take().unwrap(); let ui_renderable = self.ui_renderable.take().unwrap(); + let send_packet_events = self.send_packet_events.take().unwrap(); + let recv_packet_events = self.recv_packet_events.take().unwrap(); #[cfg(not(target_arch = "wasm32"))] { let renderer = pollster::block_on(async move { - Renderer::try_init(window.clone(), world, update_schedule, ui_renderable).await + Renderer::try_init(window.clone(), world, + update_schedule, ui_renderable, send_packet_events, recv_packet_events).await }); match renderer { Initialized(r) => { self.renderer = Some(r); } - NotReadyYet(w, u, t) => { + NotReadyYet(w, u, t, send, recv) => { self.world = Some(w); self.update_schedule = Some(u); self.ui_renderable = Some(t); + self.send_packet_events = Some(send); + self.recv_packet_events = Some(recv); } } } @@ -98,7 +110,8 @@ impl ApplicationHandler for App { self.renderer_rx = Some(rx); wasm_bindgen_futures::spawn_local(async move { let renderer = - Renderer::try_init(window.clone(), world, update_schedule, ui_renderable).await; + Renderer::try_init(window.clone(), world, + update_schedule, ui_renderable, send_packet_events, recv_packet_events).await; tx.send(renderer).unwrap(); }); } @@ -177,11 +190,11 @@ impl ApplicationHandler for App { self.renderer = Some(r); renderer_rxd = true; } - NotReadyYet(w, u, t) => { + NotReadyYet(w, u, t, send, recv) => { let (tx, rx) = futures::channel::oneshot::channel(); self.renderer_rx = Some(rx); wasm_bindgen_futures::spawn_local(async move { - let renderer = Renderer::try_init(window.clone(), w, u, t).await; + let renderer = Renderer::try_init(window.clone(), w, u, t, send, recv).await; tx.send(renderer).unwrap(); }); } @@ -210,10 +223,12 @@ impl ApplicationHandler for App { Initialized(r) => { self.renderer = Some(r); } - NotReadyYet(w, u, t) => { + NotReadyYet(w, u, t, send, recv) => { self.world = Some(w); self.update_schedule = Some(u); self.ui_renderable = Some(t); + self.send_packet_events = Some(send); + self.recv_packet_events = Some(recv); } } diff --git a/crates/client/src/rendering/renderer.rs b/crates/client/src/rendering/renderer.rs index 14c61022edc55861a09c1a45cf29e8b78585ef64..27aacbb093879579fc49b585fec66e3eb871da64 100644 --- a/crates/client/src/rendering/renderer.rs +++ b/crates/client/src/rendering/renderer.rs @@ -1,12 +1,15 @@ -use crate::ecs::{Camera, Rotation, Scale, Shear, SpriteTexture, Translation}; +use crate::ecs::{Camera, RecvPacket, Rotation, Scale, SendPacket, Shear, SpriteTexture, Translation}; +use crate::networking::ws::Ws; use crate::rendering::assets::Assets; use crate::rendering::mipmap::MipGenerator; use crate::rendering::renderer::RenderInitRes::{Initialized, NotReadyYet}; use crate::rendering::texture; use crate::rendering::ui::UiRenderable; +use bevy_ecs::event::Events; use bevy_ecs::schedule::Schedule; use bevy_ecs::world::World; use egui::ViewportId; +use futures::SinkExt; use std::collections::HashMap; use std::fmt::{Debug, Formatter}; use std::sync::Arc; @@ -39,6 +42,8 @@ pub struct Renderer { pub world: World, pub update_schedule: Schedule, + pub send_packet_events: Events, + pub recv_packet_events: Events, pub gui_ctx: egui::Context, pub gui_winit: egui_winit::State, @@ -61,7 +66,7 @@ pub struct Renderer { #[allow(clippy::large_enum_variant)] pub enum RenderInitRes { Initialized(Renderer), - NotReadyYet(World, Schedule, T), + NotReadyYet(World, Schedule, T, Events, Events), } impl Debug for RenderInitRes { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { @@ -78,10 +83,13 @@ impl Renderer { world: World, update_schedule: Schedule, gui_renderable: T, + send_packet_events: Events, + recv_packet_events: Events, ) -> RenderInitRes { let size = window.inner_size(); if size.width == 0 || size.height == 0 { - return NotReadyYet(world, update_schedule, gui_renderable); + return NotReadyYet(world, update_schedule, gui_renderable, + send_packet_events, recv_packet_events); } // First, create an instance. This is our handle to wgpu, and is the equivalent of navigator.gpu in WebGPU @@ -190,6 +198,8 @@ impl Renderer { sprite_pipeline, world, update_schedule, + send_packet_events, + recv_packet_events, gui_ctx: gui_context, gui_winit, gui_renderer, @@ -205,8 +215,14 @@ impl Renderer { } pub fn render(&mut self) { + let mut ws = self.world.get_resource_mut::().expect("Failed to get Ws resource"); + while let Ok(Some(packet)) = ws.receiver.try_next() { + self.recv_packet_events.send(RecvPacket(packet)); + } // update the world self.update_schedule.run(&mut self.world); + self.send_packet_events.update(); + self.recv_packet_events.update(); // update the UI let egui_output = self .gui_ctx @@ -285,7 +301,6 @@ impl Renderer { } u => panic!("unknown texture {u}, has it been added in rendering::renderer::::render()?") }; - tracing::warn!("{:?}", b); /*let b: &[u8] = match tex.texture.as_str() { "f" => include_bytes!("../textures/f.png"), "happy-tree" => include_bytes!("../textures/happy-tree.png"), @@ -398,6 +413,11 @@ impl Renderer { self.gui_renderer.free_texture(&id); } } + let mut ws = self.world.get_resource_mut::().expect("Failed to get Ws resource"); + let mut send_event_cursor = self.send_packet_events.get_cursor(); + for event in send_event_cursor.read(&self.send_packet_events) { + ws.send_packet(&event.0); + } let buffer = encoder.finish(); self.queue.submit(std::iter::once(buffer)); diff --git a/crates/common/Cargo.toml b/crates/common/Cargo.toml index 90875d2b826b939a42bca80c7ba52e6bf119a1c5..6318577b6d88cb38bcb520d0d7e7e426ed0f8e55 100644 --- a/crates/common/Cargo.toml +++ b/crates/common/Cargo.toml @@ -7,7 +7,8 @@ edition = "2021" [dependencies] serde = { version = "1", features = ["derive"] } +serde_json = "1" rmp-serde = "1" hmac = "0.12" sha2 = "0.10" -base64 = "0.21" \ No newline at end of file +base64 = "0.21" diff --git a/crates/common/src/lib.rs b/crates/common/src/lib.rs index c30ea4c0d13ba3fe3a3c0c1192d76fe5eb89652c..71343ab05ee5d6b46c50a55d6b2439a4cdb37d38 100644 --- a/crates/common/src/lib.rs +++ b/crates/common/src/lib.rs @@ -20,6 +20,8 @@ use serde::{Deserialize, Serialize}; use sha2::Sha256; use std::error::Error; +pub mod packet; + #[derive(Clone, Serialize, Deserialize, Debug, PartialEq)] pub struct SaveData { // ---------------------------------------------------------------------- @@ -39,8 +41,9 @@ pub struct SaveModule { pub children: Vec>, } -#[derive(Clone, Copy, PartialEq, Hash, Eq, Serialize, Deserialize, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Debug, Default)] pub enum PartType { + #[default] Placeholder, Hearty, Cargo, @@ -49,6 +52,21 @@ pub enum PartType { LandingThrusterSuspension, } +#[derive(Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] +pub enum PlanetType { + Sun, + Mercury, + Venus, + Earth, + Moon, + Mars, + Jupiter, + Saturn, + Uranus, + Neptune, + Pluto, +} + // no touchy. this is the struct that savefiles are actually represented in #[derive(Serialize, Deserialize, Clone, PartialEq, Debug)] pub struct Savefile { diff --git a/crates/server/src/packet.rs b/crates/common/src/packet.rs similarity index 79% rename from crates/server/src/packet.rs rename to crates/common/src/packet.rs index f417c54c601b8f80006a5af6cff75fbcbc3a60b8..aaa753b3bd554ddcbffb8f1aef66bb986d896dfa 100644 --- a/crates/server/src/packet.rs +++ b/crates/common/src/packet.rs @@ -1,6 +1,6 @@ use std::fmt::{Display, Formatter}; // StarKingdoms.IO, a browser game about drifting through space -// Copyright (C) 2023 ghostly_zsh, TerraMaster85, core +// Copyright (C) 2024 ghostly_zsh, TerraMaster85, core // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by @@ -15,9 +15,8 @@ use std::fmt::{Display, Formatter}; // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . use serde::{Deserialize, Serialize}; -use tungstenite::Message; -use crate::{module::component::PartType, planet::PlanetType}; +use crate::{PartType, PlanetType}; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct ProtoTransform { @@ -147,9 +146,9 @@ pub enum Packet { }, } -impl From for Message { +impl From for String { fn from(val: Packet) -> Self { - Message::Text(serde_json::to_string(&val).expect("failed to serialize packet to json")) + serde_json::to_string(&val).expect("failed to serialize packet to json") } } @@ -163,18 +162,28 @@ impl Display for MsgFromError { write!(f, "{:?}", self) } } +/* +match value { + Message::Text(s) => serde_json::from_str(s).map_err(MsgFromError::JSONError), + Message::Binary(b) => serde_json::from_slice(b).map_err(MsgFromError::JSONError), + Message::Close(_) => Ok(Packet::_SpecialDisconnect {}), + Message::Frame(_) | Message::Pong(_) | Message::Ping(_) => { + Err(MsgFromError::InvalidMessageType) + } +} +*/ -impl TryFrom<&Message> for Packet { +impl TryFrom<&String> for Packet { type Error = MsgFromError; - fn try_from(value: &Message) -> Result { - match value { - Message::Text(s) => serde_json::from_str(s).map_err(MsgFromError::JSONError), - Message::Binary(b) => serde_json::from_slice(b).map_err(MsgFromError::JSONError), - Message::Close(_) => Ok(Packet::_SpecialDisconnect {}), - Message::Frame(_) | Message::Pong(_) | Message::Ping(_) => { - Err(MsgFromError::InvalidMessageType) - } - } + fn try_from(value: &String) -> Result { + serde_json::from_str(value).map_err(MsgFromError::JSONError) + } +} +impl TryFrom<&Vec> for Packet { + type Error = MsgFromError; + + fn try_from(value: &Vec) -> Result { + serde_json::from_slice(value).map_err(MsgFromError::JSONError) } } diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs index b837facd6549c48b493669d2bae1c5cfd76a3cbd..c7b69c8b134c2d3c4eaf88f0153d6f70ba746f94 100644 --- a/crates/server/src/main.rs +++ b/crates/server/src/main.rs @@ -27,7 +27,6 @@ use bevy_rapier2d::prelude::*; use module::component::{ Attach, CanAttach, LooseAttach, ModuleTimer, PartBundle, PartFlags, PartType, }; -use packet::*; use serde::{Deserialize, Serialize}; use std::fs; @@ -41,7 +40,6 @@ pub mod crafting; pub mod macros; pub mod mathutil; pub mod module; -pub mod packet; pub mod planet; pub mod player; pub mod ws; diff --git a/crates/server/src/module/component.rs b/crates/server/src/module/component.rs index eb96cf26164294a073e513c18fa3b86b3075b0a2..b658a69dad4eb23c0592531cd561972f591c792a 100644 --- a/crates/server/src/module/component.rs +++ b/crates/server/src/module/component.rs @@ -6,37 +6,16 @@ use serde::{Deserialize, Serialize}; use starkingdoms_common::PartType as c_PartType; #[derive(Component, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Debug, Default)] -pub enum PartType { - #[default] - Placeholder, - Hearty, - Cargo, - Hub, - LandingThruster, - LandingThrusterSuspension, -} +pub struct PartType(pub c_PartType); + impl From for c_PartType { fn from(value: PartType) -> Self { - match value { - PartType::Placeholder => c_PartType::Placeholder, - PartType::Hearty => c_PartType::Hearty, - PartType::Cargo => c_PartType::Cargo, - PartType::Hub => c_PartType::Hub, - PartType::LandingThruster => c_PartType::LandingThruster, - PartType::LandingThrusterSuspension => c_PartType::LandingThrusterSuspension, - } + value.0 } } impl From for PartType { fn from(value: c_PartType) -> Self { - match value { - c_PartType::Placeholder => PartType::Placeholder, - c_PartType::Hearty => PartType::Hearty, - c_PartType::Cargo => PartType::Cargo, - c_PartType::Hub => PartType::Hub, - c_PartType::LandingThruster => PartType::LandingThruster, - c_PartType::LandingThrusterSuspension => PartType::LandingThrusterSuspension, - } + PartType(value) } } diff --git a/crates/server/src/module/mod.rs b/crates/server/src/module/mod.rs index eaf715eb165351aef476bb14d54a67d507368e32..5e61fbf6a2ee5eab60998b224a185d78ebbd2794 100644 --- a/crates/server/src/module/mod.rs +++ b/crates/server/src/module/mod.rs @@ -4,11 +4,18 @@ use bevy::{math::vec2, prelude::*}; use bevy_rapier2d::prelude::*; use component::*; use rand::Rng; +use starkingdoms_common::packet::Packet; +use starkingdoms_common::packet::Part; +use starkingdoms_common::proto_part_flags; +use starkingdoms_common::proto_transform; +use crate::ws::PacketMessageConvert; use crate::{ capacity, config::StkConfig, part, planet::PlanetType, player::component::Player, - proto_part_flags, proto_transform, ws::WsEvent, Packet, Part, + ws::WsEvent, }; +use starkingdoms_common::PartType as c_PartType; +use starkingdoms_common::PlanetType as c_PlanetType; pub mod component; pub mod save; @@ -37,7 +44,7 @@ pub fn module_spawn( transform.translation += Vec3::new(6000.0, 0.0, 0.0); let flags = PartFlags { attached: false }; let mut entity = commands.spawn(PartBundle { - part_type: PartType::Cargo, + part_type: c_PartType::Cargo.into(), transform: TransformBundle::from(transform), flags, ..default() @@ -50,21 +57,21 @@ pub fn module_spawn( }) .insert(AdditionalMassProperties::MassProperties(MassProperties { local_center_of_mass: vec2(0.0, 0.0), - mass: part!(PartType::Cargo).mass, + mass: part!(c_PartType::Cargo.into()).mass, principal_inertia: 7.5, })); let packet = Packet::SpawnPart { id: entity.id().index(), part: Part { - part_type: PartType::Cargo, + part_type: c_PartType::Cargo.into(), transform: proto_transform!(transform), flags: proto_part_flags!(flags), }, }; packet_send.send(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); } } @@ -111,12 +118,12 @@ pub fn detach_recursive( (entity, part_type, attach, flags) } else { let (entity, _, _, _, attach, part_flags) = player_query.get_mut(this).unwrap(); - (entity, &PartType::Hearty, attach, part_flags) + (entity, &c_PartType::Hearty.into(), attach, part_flags) }; energy += capacity!(*part_type); commands.entity(entity).remove::(); flags.attached = false; - if *part_type == PartType::LandingThrusterSuspension { + if *part_type == c_PartType::LandingThrusterSuspension .into(){ let parent = attach.parent.unwrap(); let parent_attach = attached_query.get(parent).unwrap().3; commands.entity(parent).insert(LooseAttach { @@ -163,7 +170,7 @@ pub fn despawn_module_tree( }; packets.push(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); let attach = match attached_query.get(*child) { @@ -232,7 +239,7 @@ pub fn attach_on_module_tree( for this in attach.clone().children.iter().flatten() { let module = part_query.get(select).unwrap(); let part_type = *module.1; - ret |= if part_type != PartType::LandingThrusterSuspension { + ret |= if part_type != c_PartType::LandingThrusterSuspension.into() { attach_on_module_tree( x, y, @@ -329,7 +336,7 @@ pub fn attach_on_module_tree( .local_basis1(angle_offset); let mut children = [None, None, None, None]; if let Some(loose_attach) = module.4 { - if *module.1 == PartType::LandingThruster { + if *module.1 == c_PartType::LandingThruster.into() { commands .entity(loose_attach.children[2].unwrap()) .insert(Attach { @@ -352,7 +359,7 @@ pub fn attach_on_module_tree( attach.children[attachment_slot] = Some(module.0); module.5.attached = true; player_query.get_mut(player_id).unwrap().1.energy_capacity += capacity!(*module.1); - if *module.1 == PartType::LandingThruster { + if *module.1 == c_PartType::LandingThruster.into() { let loose_attach = module.4.unwrap().clone(); let mut transform = part_query .get_mut(loose_attach.children[2].unwrap()) @@ -472,13 +479,13 @@ fn convert_modules_recursive( module_transform, part_flags, ) = attached_query.get_mut(*child).unwrap(); - if *part_type == PartType::Cargo { - match planet_type { - PlanetType::Mars => { - *part_type = PartType::Hub; + if *part_type == c_PartType::Cargo.into() { + match planet_type.0 { + c_PlanetType::Mars => { + *part_type = c_PartType::Hub.into(); *mass_prop = AdditionalMassProperties::MassProperties(MassProperties { local_center_of_mass: Vec2::new(0.0, 0.0), - mass: part!(PartType::Hub).mass, + mass: part!(c_PartType::Hub.into()).mass, principal_inertia: 7.5, }); let (mut collider, mut transform, _) = @@ -494,32 +501,32 @@ fn convert_modules_recursive( .unwrap() .insert(CanAttach(15)); - increase_capacity_by += part!(PartType::Hub).energy_capacity; + increase_capacity_by += part!(c_PartType::Hub.into()).energy_capacity; let packet = Packet::DespawnPart { id: child.index() }; packet_send.send(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); let packet = Packet::SpawnPart { id: child.index(), part: Part { - part_type: PartType::Hub, + part_type: c_PartType::Hub.into(), transform: proto_transform!(transform), flags: proto_part_flags!(part_flags), }, }; packet_send.send(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); } - PlanetType::Moon => { - *part_type = PartType::LandingThruster; + c_PlanetType::Moon => { + *part_type = c_PartType::LandingThruster.into(); *mass_prop = AdditionalMassProperties::MassProperties(MassProperties { local_center_of_mass: Vec2::new(0.0, 0.0), - mass: part!(PartType::LandingThruster).mass, + mass: part!(c_PartType::LandingThruster.into()).mass, principal_inertia: 7.5, }); let (mut collider, mut transform, _) = @@ -535,7 +542,7 @@ fn convert_modules_recursive( .build(); let mut suspension = commands.spawn(PartBundle { transform: TransformBundle::from(*module_transform), - part_type: PartType::LandingThrusterSuspension, + part_type: c_PartType::LandingThrusterSuspension.into(), flags: PartFlags { attached: false }, ..default() }); @@ -558,44 +565,44 @@ fn convert_modules_recursive( }); attach.children[2] = Some(suspension.id()); - increase_capacity_by += part!(PartType::LandingThruster).energy_capacity; + increase_capacity_by += part!(c_PartType::LandingThruster.into()).energy_capacity; let packet = Packet::DespawnPart { id: child.index() }; packet_send.send(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); let packet = Packet::SpawnPart { id: child.index(), part: Part { - part_type: PartType::LandingThruster, + part_type: c_PartType::LandingThruster.into(), transform: proto_transform!(transform), flags: proto_part_flags!(part_flags), }, }; packet_send.send(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); let packet = Packet::SpawnPart { id: suspension.id().index(), part: Part { - part_type: PartType::LandingThrusterSuspension, + part_type: c_PartType::LandingThrusterSuspension.into(), transform: proto_transform!(transform), flags: proto_part_flags!(part_flags), }, }; packet_send.send(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); } _ => {} } } - if *part_type != PartType::LandingThruster { + if part_type.0 != c_PartType::LandingThruster { increase_capacity_by += convert_modules_recursive( commands, planet_type, @@ -640,7 +647,7 @@ pub fn break_modules( let joints = rapier_context.entity2impulse_joint(); let mut detach_list = Vec::new(); for (entity, part_type, _, attach, _, _, _, mut flags) in &mut attached_query { - if *part_type == PartType::LandingThrusterSuspension { + if part_type.0 == c_PartType::LandingThrusterSuspension { continue; } let handle = joints.get(&entity).unwrap(); diff --git a/crates/server/src/module/save.rs b/crates/server/src/module/save.rs index 08e342edad20ca5c0bf7c3787964dc06206544fb..06a3e0d7124fffa9369d3fe27fd995bbcba90b58 100644 --- a/crates/server/src/module/save.rs +++ b/crates/server/src/module/save.rs @@ -2,11 +2,11 @@ use std::{collections::HashMap, f32::consts::PI}; use bevy::{math::vec2, prelude::*}; use bevy_rapier2d::prelude::*; -use starkingdoms_common::SaveModule; +use starkingdoms_common::{packet::Packet, PartType as c_PartType, SaveModule}; use crate::{ - capacity, mass, planet::PlanetType, player::component::Player, ws::WsEvent, Attach, CanAttach, - LooseAttach, Packet, PartBundle, PartFlags, PartType, + capacity, mass, planet::PlanetType, player::component::Player, ws::{PacketMessageConvert, WsEvent}, Attach, CanAttach, + LooseAttach, PartBundle, PartFlags, PartType, }; pub fn load_savefile( @@ -102,7 +102,7 @@ pub fn load_savefile( module.id() }; - let children = if part_type != PartType::LandingThruster { + let children = if part_type.0 != c_PartType::LandingThruster { let (children, count) = load_savefile( commands, transform, @@ -150,22 +150,22 @@ pub fn load_savefile( module .with_children(|children| { children - .spawn(if part_type == PartType::Cargo { + .spawn(if part_type.0 == c_PartType::Cargo { Collider::cuboid(0.375, 0.46875) - } else if part_type == PartType::Hub { + } else if part_type.0 == c_PartType::Hub { Collider::cuboid(0.5, 0.5) - } else if part_type == PartType::LandingThruster { + } else if part_type.0 == c_PartType::LandingThruster { Collider::cuboid(0.5, 0.375) } else { Collider::cuboid(0.5, 0.5) }) .insert(TransformBundle::from(Transform::from_xyz( 0., - if part_type == PartType::Cargo { + if part_type.0 == c_PartType::Cargo { 0.03125 - } else if part_type == PartType::Hub { + } else if part_type.0 == c_PartType::Hub { 0. - } else if part_type == PartType::LandingThruster { + } else if part_type.0 == c_PartType::LandingThruster { 0.125 } else { 0. @@ -178,7 +178,7 @@ pub fn load_savefile( mass: mass!(part_type), principal_inertia: 7.5, })); - if part_type == PartType::Hub { + if part_type.0 == c_PartType::Hub { module.insert(CanAttach(15)); } @@ -188,7 +188,7 @@ pub fn load_savefile( module.insert(ImpulseJoint::new(parent, joint)); - if part_type == PartType::LandingThruster { + if part_type.0 == c_PartType::LandingThruster { let joint = PrismaticJointBuilder::new(Vec2::new(0., 1.)) .set_motor(0., 0., 3000., 3000.) .limits([0., 1.]) @@ -207,7 +207,7 @@ pub fn load_savefile( 0., )), ), - part_type: PartType::LandingThrusterSuspension, + part_type: c_PartType::LandingThrusterSuspension.into(), flags: PartFlags { attached: true }, ..default() }); @@ -263,7 +263,7 @@ pub fn construct_save_data( for (i, child) in attach.children.iter().enumerate() { if let Some(child) = child { let (_, part_type, _, attach, _, _, _, _) = attached_query.get(*child).unwrap(); - if *part_type == PartType::LandingThrusterSuspension { + if part_type.0 == c_PartType::LandingThrusterSuspension { continue; } let child_save_module = construct_save_data(attach.clone(), attached_query); @@ -352,7 +352,7 @@ pub fn save_eligibility( packet_send.send(WsEvent::Send { to: player.addr, - message: packet.into(), + message: packet.into_message(), }); } } diff --git a/crates/server/src/module/thruster.rs b/crates/server/src/module/thruster.rs index b8cb4b6af3b10fb2c475e4c5da82bbd7885f9f49..aebc9fe9bdec98bedec7c7e35d6356073722bbc3 100644 --- a/crates/server/src/module/thruster.rs +++ b/crates/server/src/module/thruster.rs @@ -7,6 +7,7 @@ use crate::{ }; use bevy::prelude::*; use bevy_rapier2d::prelude::*; +use starkingdoms_common::PartType as c_PartType; pub fn search_thrusters( input: Input, @@ -35,9 +36,9 @@ pub fn search_thrusters( let mut force_mult = 0.; let mut energy_lose_by = 0; - if *part_type == PartType::LandingThruster { - force_mult = part!(PartType::LandingThruster).thruster_force; - energy_lose_by = part!(PartType::LandingThruster).thruster_energy; + if part_type.0 == c_PartType::LandingThruster { + force_mult = part!(c_PartType::LandingThruster.into()).thruster_force; + energy_lose_by = part!(c_PartType::LandingThruster.into()).thruster_energy; } if input.up && 3. * PI / 4. < relative_angle && relative_angle < 5. * PI / 4. { let thruster_force = ExternalForce::at_point( @@ -165,7 +166,7 @@ pub fn search_thrusters( } } - if *part_type != PartType::LandingThruster && *energy >= energy_lose_by { + if part_type.0 != c_PartType::LandingThruster && *energy >= energy_lose_by { search_thrusters(input, attach.clone(), p_transform, energy, attached_query); } } diff --git a/crates/server/src/planet.rs b/crates/server/src/planet.rs index fdcf6b141593274612a4b4bd38dd7e54b2af02ce..f4cf36d34e6969c8d35d97812b9144fff2cce54f 100644 --- a/crates/server/src/planet.rs +++ b/crates/server/src/planet.rs @@ -3,21 +3,10 @@ use bevy_rapier2d::prelude::*; use serde::{Deserialize, Serialize}; use crate::{config::StkConfig, module::component::PartType, planet}; +use starkingdoms_common::PlanetType as c_PlanetType; #[derive(Component, Clone, Copy, Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] -pub enum PlanetType { - Sun, - Mercury, - Venus, - Earth, - Moon, - Mars, - Jupiter, - Saturn, - Uranus, - Neptune, - Pluto, -} +pub struct PlanetType(pub c_PlanetType); #[derive(Bundle)] pub struct PlanetBundle { @@ -30,17 +19,17 @@ pub fn spawn_planets(mut commands: Commands) { let sun_pos = Transform::from_xyz(0.0, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Sun, + planet_type: PlanetType(c_PlanetType::Sun), transform: TransformBundle::from(sun_pos), }) - .insert(Collider::ball(planet!(PlanetType::Sun).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Sun)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Sun).mass, + planet!(PlanetType(c_PlanetType::Sun)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Sun).size + 0.3)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Sun)).size + 0.3)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -48,17 +37,17 @@ pub fn spawn_planets(mut commands: Commands) { let mercury_pos = Transform::from_xyz(2322.588, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Mercury, + planet_type: PlanetType(c_PlanetType::Mercury), transform: TransformBundle::from(mercury_pos), }) - .insert(Collider::ball(planet!(PlanetType::Mercury).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Mercury)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Mercury).mass, + planet!(PlanetType(c_PlanetType::Mercury)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Mercury).size + 0.3)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Mercury)).size + 0.3)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -66,17 +55,17 @@ pub fn spawn_planets(mut commands: Commands) { let venus_pos = Transform::from_xyz(4339.992, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Venus, + planet_type: PlanetType(c_PlanetType::Venus), transform: TransformBundle::from(venus_pos), }) - .insert(Collider::ball(planet!(PlanetType::Venus).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Venus)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Venus).mass, + planet!(PlanetType(c_PlanetType::Venus)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Venus).size + 0.3)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Venus)).size + 0.3)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -84,17 +73,17 @@ pub fn spawn_planets(mut commands: Commands) { let earth_pos = Transform::from_xyz(6000.0, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Earth, + planet_type: PlanetType(c_PlanetType::Earth), transform: TransformBundle::from(earth_pos), }) - .insert(Collider::ball(planet!(PlanetType::Earth).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Earth)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Earth).mass, + planet!(PlanetType(c_PlanetType::Earth)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Earth).size + 0.3)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Earth)).size + 0.3)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -102,17 +91,17 @@ pub fn spawn_planets(mut commands: Commands) { let moon_pos = Transform::from_xyz(6030.828, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Moon, + planet_type: PlanetType(c_PlanetType::Moon), transform: TransformBundle::from(moon_pos), }) - .insert(Collider::ball(planet!(PlanetType::Moon).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Moon)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Moon).mass, + planet!(PlanetType(c_PlanetType::Moon)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Moon).size + 0.1)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Moon)).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -120,17 +109,17 @@ pub fn spawn_planets(mut commands: Commands) { let mars_pos = Transform::from_xyz(9142.0833, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Mars, + planet_type: PlanetType(c_PlanetType::Mars), transform: TransformBundle::from(mars_pos), }) - .insert(Collider::ball(planet!(PlanetType::Mars).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Mars)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Mars).mass, + planet!(PlanetType(c_PlanetType::Mars)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Mars).size + 0.1)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Mars)).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -138,17 +127,17 @@ pub fn spawn_planets(mut commands: Commands) { let jupiter_pos = Transform::from_xyz(31222.8, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Jupiter, + planet_type: PlanetType(c_PlanetType::Jupiter), transform: TransformBundle::from(jupiter_pos), }) - .insert(Collider::ball(planet!(PlanetType::Jupiter).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Jupiter)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Jupiter).mass, + planet!(PlanetType(c_PlanetType::Jupiter)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Jupiter).size + 0.1)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Jupiter)).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -156,17 +145,17 @@ pub fn spawn_planets(mut commands: Commands) { let saturn_pos = Transform::from_xyz(57495.6, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Saturn, + planet_type: PlanetType(c_PlanetType::Saturn), transform: TransformBundle::from(saturn_pos), }) - .insert(Collider::ball(planet!(PlanetType::Saturn).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Saturn)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Saturn).mass, + planet!(PlanetType(c_PlanetType::Saturn)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Saturn).size + 0.1)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Saturn)).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -174,17 +163,17 @@ pub fn spawn_planets(mut commands: Commands) { let uranus_pos = Transform::from_xyz(115147.56, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Uranus, + planet_type: PlanetType(c_PlanetType::Uranus), transform: TransformBundle::from(uranus_pos), }) - .insert(Collider::ball(planet!(PlanetType::Uranus).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Uranus)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Uranus).mass, + planet!(PlanetType(c_PlanetType::Uranus)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Uranus).size + 0.1)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Uranus)).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -192,17 +181,17 @@ pub fn spawn_planets(mut commands: Commands) { let neptune_pos = Transform::from_xyz(180420.0, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Neptune, + planet_type: PlanetType(c_PlanetType::Neptune), transform: TransformBundle::from(neptune_pos), }) - .insert(Collider::ball(planet!(PlanetType::Neptune).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Neptune)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Neptune).mass, + planet!(PlanetType(c_PlanetType::Neptune)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Neptune).size + 0.1)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Neptune)).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) @@ -210,17 +199,17 @@ pub fn spawn_planets(mut commands: Commands) { let pluto_pos = Transform::from_xyz(236892.0, 0.0, 0.0); commands .spawn(PlanetBundle { - planet_type: PlanetType::Pluto, + planet_type: PlanetType(c_PlanetType::Pluto), transform: TransformBundle::from(pluto_pos), }) - .insert(Collider::ball(planet!(PlanetType::Pluto).size)) + .insert(Collider::ball(planet!(PlanetType(c_PlanetType::Pluto)).size)) .insert(AdditionalMassProperties::Mass( - planet!(PlanetType::Pluto).mass, + planet!(PlanetType(c_PlanetType::Pluto)).mass, )) .insert(ReadMassProperties::default()) .with_children(|children| { children - .spawn(Collider::ball(planet!(PlanetType::Pluto).size + 0.1)) + .spawn(Collider::ball(planet!(PlanetType(c_PlanetType::Pluto)).size + 0.1)) .insert(ActiveEvents::COLLISION_EVENTS) .insert(Sensor); }) diff --git a/crates/server/src/player/client_login.rs b/crates/server/src/player/client_login.rs index 40afab1d995b0bb4ca6b2c2f6467b25939a85dae..0440db9bf2786d30c78e630c250fb5aa00ef86c8 100644 --- a/crates/server/src/player/client_login.rs +++ b/crates/server/src/player/client_login.rs @@ -6,7 +6,7 @@ use hmac::{Hmac, Mac}; use jwt::VerifyWithKey; use rand::Rng; use sha2::Sha256; -use starkingdoms_common::unpack_savefile; +use starkingdoms_common::{packet::{MessageType, Packet, Part, Planet, ProtoPartFlags}, proto_part_flags, proto_transform, unpack_savefile, PartType as c_PartType, PlanetType as c_PlanetType}; use crate::{ config::StkConfig, @@ -15,9 +15,8 @@ use crate::{ save::load_savefile, }, planet::PlanetType, - proto_part_flags, proto_transform, - ws::WsEvent, - AppKeys, MessageType, Packet, Part, Planet, ProtoPartFlags, UserToken, CLIENT_SCALE, + ws::{PacketMessageConvert, WsEvent}, + AppKeys, UserToken, CLIENT_SCALE, }; use super::component::{Input, Player}; @@ -36,7 +35,7 @@ pub fn join_auth( Err(e) => { event_queue.push(WsEvent::Send { to: *from, - message: Packet::Message { message_type: MessageType::Error, actor: "SERVER".to_string(), content: format!("Token is invalid or verification failed: {e}. Please log in again, or contact StarKingdoms staff if the problem persists.") }.into(), + message: Packet::Message { message_type: MessageType::Error, actor: "SERVER".to_string(), content: format!("Token is invalid or verification failed: {e}. Please log in again, or contact StarKingdoms staff if the problem persists.") }.into_message(), }); event_queue.push(WsEvent::Close { addr: *from }); return false; @@ -46,7 +45,7 @@ pub fn join_auth( if claims.permission_level < server_config.security.required_permission_level { event_queue.push(WsEvent::Send { to: *from, - message: Packet::Message { message_type: MessageType::Error, actor: "SERVER".to_string(), content: format!("Permission level {} is too low, {} is required. If your permissions were just changed, you need to log out and log back in for the change to take effect. If you believe this is a mistake, contact StarKingdoms staff.", claims.permission_level, server_config.security.required_permission_level) }.into(), + message: Packet::Message { message_type: MessageType::Error, actor: "SERVER".to_string(), content: format!("Permission level {} is too low, {} is required. If your permissions were just changed, you need to log out and log back in for the change to take effect. If you believe this is a mistake, contact StarKingdoms staff.", claims.permission_level, server_config.security.required_permission_level) }.into_message(), }); event_queue.push(WsEvent::Close { addr: *from }); return false; @@ -54,12 +53,12 @@ pub fn join_auth( event_queue.push(WsEvent::Send { to: *from, - message: Packet::Message { message_type: MessageType::Server, actor: "StarKingdoms Team".to_string(), content: "Thank you for participating in the StarKingdoms private alpha! Your feedback is essential to improving the game, so please give us any feedback you have in the Discord! <3".to_string() }.into(), + message: Packet::Message { message_type: MessageType::Server, actor: "StarKingdoms Team".to_string(), content: "Thank you for participating in the StarKingdoms private alpha! Your feedback is essential to improving the game, so please give us any feedback you have in the Discord! <3".to_string() }.into_message(), }); } else if server_config.security.required_permission_level != 0 { event_queue.push(WsEvent::Send { to: *from, - message: Packet::Message { message_type: MessageType::Error, actor: "SERVER".to_string(), content: "Authentication is required to join this server at the moment. Log in and try again, or try again later.".to_string() }.into(), + message: Packet::Message { message_type: MessageType::Error, actor: "SERVER".to_string(), content: "Authentication is required to join this server at the moment. Log in and try again, or try again later.".to_string() }.into_message(), }); event_queue.push(WsEvent::Close { addr: *from }); return false; @@ -87,11 +86,11 @@ pub fn spawn_player( input: Input::default(), selected: None, save_eligibility: false, - energy_capacity: part!(PartType::Hearty).energy_capacity, - energy: part!(PartType::Hearty).energy_capacity, + energy_capacity: part!(c_PartType::Hearty.into()).energy_capacity, + energy: part!(c_PartType::Hearty.into()).energy_capacity, }; let mut entity_id = commands.spawn(PartBundle { - part_type: PartType::Hearty, + part_type: c_PartType::Hearty.into(), transform: TransformBundle::from(transform), flags: PartFlags { attached: false }, ..default() @@ -100,7 +99,7 @@ pub fn spawn_player( .insert(Collider::cuboid(0.5, 0.5)) .insert(AdditionalMassProperties::MassProperties(MassProperties { local_center_of_mass: vec2(0.0, 0.0), - mass: part!(PartType::Hearty).mass, + mass: part!(c_PartType::Hearty.into()).mass, principal_inertia: 7.5, })); (entity_id.id(), transform, player_comp) @@ -174,13 +173,13 @@ pub fn load_save( attach.children = children; } else { let packet = Packet::Message { - message_type: crate::packet::MessageType::Error, + message_type: MessageType::Error, actor: "SERVER".to_string(), content: "Savefile signature corrupted or inner data invalid. Save was not loaded. Contact StarKingdoms staff for assistance.".to_string(), }; event_queue.push(WsEvent::Send { to: *from, - message: packet.into(), + message: packet.into_message(), }); } } else { @@ -238,7 +237,7 @@ pub fn packet_stream( planets.push(( entity.index(), Planet { - planet_type: *planet_type, + planet_type: planet_type.0, transform: proto_transform!(Transform::from_translation( translation * CLIENT_SCALE )), @@ -249,7 +248,7 @@ pub fn packet_stream( let packet = Packet::PlanetPositions { planets }; event_queue.push(WsEvent::Send { to: *from, - message: packet.into(), + message: packet.into_message(), }); // tell the player already existing users @@ -260,7 +259,7 @@ pub fn packet_stream( let packet = Packet::PlayerList { players }; event_queue.push(WsEvent::Send { to: *from, - message: packet.into(), + message: packet.into_message(), }); // tell other players that a player has spawned in @@ -269,15 +268,15 @@ pub fn packet_stream( username: username.to_string(), }; event_queue.push(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); let packet = Packet::Message { - message_type: crate::packet::MessageType::Server, + message_type: MessageType::Server, actor: "SERVER".to_string(), content: format!("{} has joined the server!", username), }; event_queue.push(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); // tell the player where parts are @@ -286,7 +285,7 @@ pub fn packet_stream( parts.push(( entity.index(), Part { - part_type: *part_type, + part_type: part_type.0, transform: proto_transform!(Transform::from_translation( transform.translation * CLIENT_SCALE )), @@ -298,7 +297,7 @@ pub fn packet_stream( parts.push(( entity.index(), Part { - part_type: *part_type, + part_type: part_type.0, transform: proto_transform!(Transform::from_translation( transform.translation * CLIENT_SCALE )), @@ -309,7 +308,7 @@ pub fn packet_stream( parts.push(( index, Part { - part_type: PartType::Hearty, + part_type: c_PartType::Hearty.into(), transform: proto_transform!(Transform::from_translation(transform.translation) .with_rotation(transform.rotation)), flags: ProtoPartFlags { attached: false }, @@ -318,12 +317,12 @@ pub fn packet_stream( let packet = Packet::PartPositions { parts }; event_queue.push(WsEvent::Send { to: *from, - message: packet.into(), + message: packet.into_message(), }); // and send the welcome message :) let packet = Packet::Message { - message_type: crate::packet::MessageType::Server, + message_type: MessageType::Server, actor: "SERVER".to_string(), content: format!( "starkingdoms-server v{} says hello", @@ -332,24 +331,24 @@ pub fn packet_stream( }; event_queue.push(WsEvent::Send { to: *from, - message: packet.into(), + message: packet.into_message(), }); let packet = Packet::Message { - message_type: crate::packet::MessageType::Server, + message_type: MessageType::Server, actor: "SERVER".to_string(), content: "Welcome to StarKingdoms.IO! Have fun!".to_string(), }; event_queue.push(WsEvent::Send { to: *from, - message: packet.into(), + message: packet.into_message(), }); let packet = Packet::Message { - message_type: crate::packet::MessageType::Server, + message_type: MessageType::Server, actor: "SERVER".to_string(), content: "Found a bug? Have a feature request? Please bring this and all other feedback to the game's official Discord server! Join here: https://discord.gg/3u7Yw8DWtQ".to_string(), }; event_queue.push(WsEvent::Send { to: *from, - message: packet.into(), + message: packet.into_message(), }); } diff --git a/crates/server/src/player/mod.rs b/crates/server/src/player/mod.rs index 3d4a653591f7441fcf49e6133a9225317ac006c2..4ee19a6f9e422066d7d147bc5aecabb58f95c0cb 100644 --- a/crates/server/src/player/mod.rs +++ b/crates/server/src/player/mod.rs @@ -5,6 +5,7 @@ use component::Player; use player_mouse_input::{attach_or_detach, mouse_picking}; use request_save::request_save; use send_message::send_message; +use starkingdoms_common::{packet::Packet, PartType as c_PartType}; use crate::{ config::StkConfig, @@ -16,8 +17,8 @@ use crate::{ }, part, planet::PlanetType, - ws::WsEvent, - AppKeys, Packet, CLIENT_SCALE, + ws::{PacketMessageConvert, WsEvent}, + AppKeys, CLIENT_SCALE, }; pub mod client_login; @@ -73,7 +74,7 @@ pub fn on_message( let mut event_queue = Vec::new(); for ev in packet_recv.read(&packet_event_send) { if let WsEvent::Recv { from, message } = ev { - let packet: Packet = err_or_cont!(message.try_into()); + let packet: Packet = err_or_cont!(Packet::from_message(message)); match packet { Packet::ClientLogin { @@ -295,12 +296,12 @@ pub fn player_input_update( // process each thruster on hearty for (force_multiplier, x_offset, y_offset) in thrusters { - if force_multiplier != 0.0 && player.energy >= part!(PartType::Hearty).thruster_energy { - player.energy -= part!(PartType::Hearty).thruster_energy; + if force_multiplier != 0.0 && player.energy >= part!(c_PartType::Hearty.into()).thruster_energy { + player.energy -= part!(c_PartType::Hearty.into()).thruster_energy; let thruster_pos_uncast = vec2(x_offset, y_offset); let thruster_pos_cast = rot2d(thruster_pos_uncast, rot) + transform.translation.xy(); - let thruster_force = force_multiplier * part!(PartType::Hearty).thruster_force; + let thruster_force = force_multiplier * part!(c_PartType::Hearty.into()).thruster_force; let thruster_vec = vec2(-thruster_force * rot.sin(), thruster_force * rot.cos()); let thruster_force = ExternalForce::at_point( thruster_vec, @@ -313,7 +314,7 @@ pub fn player_input_update( } // change to support other thruster types later // check if the player has enough energy to use thruster - if player.energy >= part!(PartType::LandingThruster).thruster_energy { + if player.energy >= part!(c_PartType::LandingThruster.into()).thruster_energy { // go through all thrusters and apply force crate::module::thruster::search_thrusters( player.input, diff --git a/crates/server/src/player/packet.rs b/crates/server/src/player/packet.rs index 89a43dbde4c30d769927dd499818a6721ddc1dfc..fb2af5446539d7fa39edb109377671252a8e7da8 100644 --- a/crates/server/src/player/packet.rs +++ b/crates/server/src/player/packet.rs @@ -1,11 +1,11 @@ use bevy::{ecs::event::ManualEventReader, prelude::*}; +use starkingdoms_common::{packet::{Packet, Part, Planet}, proto_part_flags, proto_transform}; use crate::{ module::component::{Attach, PartFlags, PartType}, planet::PlanetType, - proto_part_flags, proto_transform, - ws::WsEvent, - Packet, Part, Planet, CLIENT_SCALE, + ws::{PacketMessageConvert, WsEvent}, + CLIENT_SCALE, }; use super::component::Player; @@ -19,7 +19,7 @@ pub fn send_player_energy(player_query: Query<&Player>, mut packet_send: EventWr packet_send.send(WsEvent::Send { to: player.addr, - message: packet.into(), + message: packet.into_message(), }); } } @@ -36,7 +36,7 @@ pub fn on_position_change( updated_parts.push(( id, Part { - part_type: *part_type, + part_type: part_type.0, transform: proto_transform!(Transform::from_translation( transform.translation * CLIENT_SCALE, ) @@ -52,7 +52,7 @@ pub fn on_position_change( }; packet_send.send(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); } @@ -62,7 +62,7 @@ pub fn on_position_change( planets.push(( id, Planet { - planet_type: *planet_type, + planet_type: planet_type.0, transform: proto_transform!(Transform::from_translation( transform.translation * CLIENT_SCALE )), @@ -75,7 +75,7 @@ pub fn on_position_change( let packet = Packet::PlanetPositions { planets }; packet_send.send(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); } } @@ -108,7 +108,7 @@ pub fn on_close( if entity != in_entity { packets.push(WsEvent::Send { to: player.addr, - message: packet.clone().into(), + message: packet.clone().into_message(), }); } } diff --git a/crates/server/src/player/player_mouse_input.rs b/crates/server/src/player/player_mouse_input.rs index cac49b99bf80cf39154b61aeb0a60c1cecff475b..5fa6e0994c0ec877133ed488fcc1f4d2457b5cc1 100644 --- a/crates/server/src/player/player_mouse_input.rs +++ b/crates/server/src/player/player_mouse_input.rs @@ -5,6 +5,7 @@ use crate::{ module::component::{Attach, CanAttach, LooseAttach, PartFlags, PartType}, planet::PlanetType, }; +use starkingdoms_common::PartType as c_PartType; use super::component::Player; @@ -57,7 +58,7 @@ pub fn attach_or_detach( crate::module::detach_recursive(commands, module.0, attached_query, player_query); let mut module = attached_query.get_mut(select).unwrap(); module.2.translation = vec3(x, y, 0.); - if *module.1 == PartType::LandingThruster { + if *module.1 == c_PartType::LandingThruster.into() { let sub_entity = attach.children[2].unwrap(); let mut suspension = attached_query.get_mut(sub_entity).unwrap(); suspension.2.translation = vec3(x, y, 0.); @@ -85,7 +86,7 @@ pub fn attach_or_detach( // move module to cursor since no attach let mut part = part_query.get_mut(select).unwrap(); part.2.translation = vec3(x, y, 0.); - if *part.1 == PartType::LandingThruster { + if *part.1 == c_PartType::LandingThruster.into() { if let Some(loose_attach) = part.4 { let sub_entity = loose_attach.children[2].unwrap(); let mut part = part_query.get_mut(sub_entity).unwrap(); @@ -125,7 +126,7 @@ pub fn mouse_picking( entity: Entity, ) { for (m_entity, part_type, transform, m_attach, _velocity, _, _, _) in attached_query.iter() { - if *part_type == PartType::LandingThrusterSuspension { + if *part_type == c_PartType::LandingThrusterSuspension.into() { continue; } let pos = transform.translation; @@ -135,7 +136,7 @@ pub fn mouse_picking( let x = rel_x * angle.cos() - rel_y * angle.sin(); let y = rel_x * angle.sin() + rel_y * angle.cos(); let mut bound = [-0.5, 0.5, -0.5, 0.5]; // left, right, top, bottom - if let PartType::Cargo = part_type { + if let c_PartType::Cargo = part_type.0 { bound = [-0.375, 0.375, -0.5, 0.4375]; } @@ -150,7 +151,7 @@ pub fn mouse_picking( } } for (entity, part_type, transform, _, _, _) in part_query.iter() { - if *part_type == PartType::LandingThrusterSuspension { + if *part_type == c_PartType::LandingThrusterSuspension.into() { continue; } let pos = transform.translation; @@ -160,7 +161,7 @@ pub fn mouse_picking( let x = rel_x * angle.cos() - rel_y * angle.sin(); let y = rel_x * angle.sin() + rel_y * angle.cos(); let mut bound = [-0.5, 0.5, -0.5, 0.5]; // left, right, top, bottom - if let PartType::Cargo = part_type { + if let c_PartType::Cargo = part_type.0 { bound = [-0.375, 0.375, -0.5, 0.4375]; } diff --git a/crates/server/src/player/request_save.rs b/crates/server/src/player/request_save.rs index 313c14f98129a6be364da9d38cc577bdd7988ce3..57fee2e68adb9d162d3ddef78355d45f64119da9 100644 --- a/crates/server/src/player/request_save.rs +++ b/crates/server/src/player/request_save.rs @@ -2,13 +2,13 @@ use std::net::SocketAddr; use bevy::prelude::*; use bevy_rapier2d::prelude::Velocity; -use starkingdoms_common::{pack_savefile, unpack_savefile, SaveData}; +use starkingdoms_common::{pack_savefile, packet::Packet, unpack_savefile, SaveData}; use crate::{ module::component::{Attach, CanAttach, LooseAttach, PartFlags, PartType}, planet::PlanetType, - ws::WsEvent, - AppKeys, Packet, + ws::{PacketMessageConvert, WsEvent}, + AppKeys, }; use super::component::Player; @@ -53,6 +53,6 @@ pub fn request_save( event_queue.push(WsEvent::Send { to: *from, - message: packet.into(), + message: packet.into_message(), }); } diff --git a/crates/server/src/player/send_message.rs b/crates/server/src/player/send_message.rs index 798957c5af62a82f2fa8c4e63429be9ddc2fb998..cf6b1f686f89688f22cf8ee08829d602c6b74248 100644 --- a/crates/server/src/player/send_message.rs +++ b/crates/server/src/player/send_message.rs @@ -2,12 +2,12 @@ use std::net::SocketAddr; use bevy::prelude::*; use bevy_rapier2d::prelude::Velocity; +use starkingdoms_common::packet::Packet; use crate::{ module::component::{Attach, PartFlags}, planet::PlanetType, - ws::WsEvent, - Packet, + ws::{PacketMessageConvert, WsEvent}, }; use super::component::Player; @@ -46,28 +46,28 @@ pub fn send_message( } let target_player = target_player.unwrap(); let packet = Packet::Message { - message_type: crate::packet::MessageType::Direct, + message_type: starkingdoms_common::packet::MessageType::Direct, actor: player.username.clone(), content, }; event_queue.push(WsEvent::Send { to: target_player.addr, - message: packet.clone().into(), + message: packet.clone().into_message(), }); event_queue.push(WsEvent::Send { to: *from, - message: packet.into(), + message: packet.into_message(), }); } else { // send to general chat let packet = Packet::Message { - message_type: crate::packet::MessageType::Chat, + message_type: starkingdoms_common::packet::MessageType::Chat, actor: player.username.clone(), content, }; event_queue.push(WsEvent::Broadcast { - message: packet.into(), + message: packet.into_message(), }); } } diff --git a/crates/server/src/ws.rs b/crates/server/src/ws.rs index d6e78dd58eaa423a8891c5ac3f87e45390632688..4d7bb4aec6b74be1584b5662467283eebd5f7ae7 100644 --- a/crates/server/src/ws.rs +++ b/crates/server/src/ws.rs @@ -19,6 +19,7 @@ use bevy::ecs::event::ManualEventReader; use bevy::log::{error, warn}; use bevy::prelude::{Commands, Event, Events, Local, Res, ResMut, Resource}; use crossbeam_channel::{unbounded, Receiver}; +use starkingdoms_common::packet::{MsgFromError, Packet}; use std::collections::HashMap; use std::net::{IpAddr, SocketAddr, TcpListener}; use std::sync::{Arc, RwLock}; @@ -39,6 +40,27 @@ impl Plugin for StkTungsteniteServerPlugin { } } +pub trait PacketMessageConvert { + fn from_message(value: &Message) -> Result; + fn into_message(self) -> Message; +} + +impl PacketMessageConvert for Packet { + fn from_message(value: &Message) -> Result { + match value { + Message::Text(s) => serde_json::from_str(s).map_err(MsgFromError::JSONError), + Message::Binary(b) => serde_json::from_slice(b).map_err(MsgFromError::JSONError), + Message::Close(_) => Ok(Packet::_SpecialDisconnect {}), + Message::Frame(_) | Message::Pong(_) | Message::Ping(_) => { + Err(MsgFromError::InvalidMessageType) + } + } + } + fn into_message(self) -> Message { + Message::Text(serde_json::to_string(&self).expect("failed to serialize packet to json")) + } +} + #[derive(Event, Clone, Debug)] pub enum WsEvent { Connection { from: SocketAddr },