M Cargo.lock => Cargo.lock +1 -0
@@ 6297,6 6297,7 @@ name = "starkingdoms-common"
version = "0.1.0"
dependencies = [
"base64 0.21.7",
+ "bevy_ecs 0.15.3",
"hmac",
"rmp-serde",
"serde",
M crates/client/Cargo.toml => crates/client/Cargo.toml +1 -1
@@ 21,7 21,7 @@ egui-winit = { version = "0.31.1", default-features = false, features = ["links"
web-time = "1"
futures = "0.3"
nalgebra = "0.33"
-starkingdoms-common = { version = "0.1", path = "../common" }
+starkingdoms-common = { version = "0.1", path = "../common", features = ["bevy"] }
serde = "1"
serde_json = "1"
crossbeam = "0.8.4"
M crates/client/src/components.rs => crates/client/src/components.rs +34 -0
@@ 1,7 1,41 @@
use bevy_ecs::{bundle::Bundle, component::Component, event::Event, system::Resource};
+use bevy_ecs::schedule::ScheduleLabel;
use nalgebra::{Matrix3, Matrix4, Rotation2, Scale2, Scale3, Translation2, Translation3};
use starkingdoms_common::packet::Packet;
+#[derive(Bundle)]
+pub struct PlayerBundle {
+ pub transform: Transform,
+ pub texture: Texture,
+ pub player: Player,
+ pub part: Part
+}
+
+#[derive(Bundle)]
+pub struct PartBundle {
+ pub transform: Transform,
+ pub texture: Texture,
+ pub server_id: ServerId,
+ pub part: Part
+}
+
+#[derive(Bundle)]
+pub struct OtherPlayerBundle {
+ pub part: PartBundle,
+ pub username: PlayerUsername
+}
+
+#[derive(ScheduleLabel, Hash, Clone, Debug, Eq, PartialEq)]
+pub enum Schedule {
+ Startup,
+ Update
+}
+
+#[derive(Component, Debug)]
+pub struct PlayerUsername {
+ pub username: String
+}
+
#[derive(Component, Debug)]
pub struct Texture {
pub name: String,
M crates/client/src/lib.rs => crates/client/src/lib.rs +35 -13
@@ 1,6 1,9 @@
use crate::components::PlayerResources;
use crate::networking::websocket::Websocket;
use bevy_ecs::{event::Events, world::World};
+use bevy_ecs::event::EventRegistry;
+use bevy_ecs::prelude::Event;
+use bevy_ecs::schedule::Schedule;
use components::{Camera, Chat, Part, Player, RecvPacket, SendPacket, Texture, Transform};
use nalgebra::{Rotation2, Scale3, Translation3};
use platform::assets::Assets;
@@ 9,6 12,10 @@ use rendering::assets::AssetLoader;
use rendering::App;
use tracing::info;
use winit::event_loop::{ControlFlow, EventLoop};
+use starkingdoms_common::packet::{ClientLoginPacket, DespawnPartPacket, EnergyUpdatePacket, LoginResponsePacket, MessagePacket, OpenCraftingUiPacket, PartPositionsPacket, PlanetPositionsPacket, PlayerInputPacket, PlayerLeavePacket, PlayerListPacket, PlayerMouseInputPacket, RequestSavePacket, SaveDataPacket, SaveEligibilityPacket, SendMessagePacket, SpawnPartPacket, SpawnPlayerPacket, SpecialDisconnectPacket};
+use crate::components::Schedule::{Startup, Update};
+use crate::networking::handlers::{handle_crafting_ui, handle_despawn_part, handle_energy_update, handle_existing_players_list, handle_login_response, handle_message, handle_part_positions, handle_player_leave, handle_spawn_part, handle_spawn_player};
+use crate::systems::create_hearty;
#[cfg(target_arch = "wasm32")]
#[path = "wasm/mod.rs"]
@@ 21,6 28,7 @@ pub mod components;
pub mod networking;
pub mod rendering;
pub mod ui;
+pub mod systems;
// Hi, you've found the real main function! This is called AFTER platform-specific initialization code.
pub fn start() {
@@ 59,18 67,32 @@ pub fn start() {
let send_packet_events = Events::<SendPacket>::default();
let recv_packet_events = Events::<RecvPacket>::default();
- world.spawn((
- Transform {
- translation: Translation3::new(0.0, 0.0, 0.0),
- rotation: Rotation2::new(0.0),
- scale: Scale3::new(25.0, 25.0, 1.0),
- },
- Texture {
- name: "hearty.svg".to_string(),
- },
- Player,
- Part(false),
- ));
+ starkingdoms_common::packet::register_packet_events(&mut world);
+
+ let mut startup_schedule = Schedule::new(Startup);
+
+ startup_schedule.add_systems(create_hearty);
+
+ let mut update_schedule = Schedule::new(Update);
+
+ update_schedule.add_systems(handle_existing_players_list);
+ update_schedule.add_systems(handle_spawn_player);
+ update_schedule.add_systems(handle_spawn_part);
+ update_schedule.add_systems(handle_part_positions);
+ update_schedule.add_systems(handle_energy_update);
+ update_schedule.add_systems(handle_crafting_ui);
+ update_schedule.add_systems(handle_message);
+ update_schedule.add_systems(handle_player_leave);
+ update_schedule.add_systems(handle_despawn_part);
+ update_schedule.add_systems(handle_login_response);
+
+
+ // add systems here
+
+ world.add_schedule(startup_schedule);
+ world.add_schedule(update_schedule);
+
+ world.run_schedule(Startup);
let event_loop = EventLoop::new().unwrap();
event_loop.set_control_flow(ControlFlow::Wait);
@@ 78,4 100,4 @@ pub fn start() {
event_loop
.run_app(&mut App::new(world, send_packet_events, recv_packet_events))
.unwrap();
-}
+}<
\ No newline at end of file
A crates/client/src/networking/handlers.rs => crates/client/src/networking/handlers.rs +153 -0
@@ 0,0 1,153 @@
+use bevy_ecs::prelude::*;
+use nalgebra::{Rotation2, Scale3, Translation3};
+use starkingdoms_common::packet::{DespawnPartPacket, EnergyUpdatePacket, LoginResponsePacket, MessagePacket, OpenCraftingUiPacket, PartPositionsPacket, PlanetPositionsPacket, PlayerLeavePacket, PlayerListPacket, SpawnPartPacket, SpawnPlayerPacket};
+use starkingdoms_common::PartType;
+use crate::components::{Camera, Chat, Menu, OtherPlayerBundle, Part, PartBundle, Player, PlayerBundle, PlayerResources, PlayerUsername, ServerId, Texture, Transform};
+use crate::networking::texture_name;
+
+pub fn handle_login_response(mut reader: EventReader<LoginResponsePacket>, mut player: Query<Entity, With<Player>>, mut commands: Commands) {
+ for packet in reader.read() {
+ let player = player.single();
+ commands.entity(player).insert(ServerId(packet.id));
+ }
+}
+
+pub fn handle_message(mut reader: EventReader<MessagePacket>, mut chat: ResMut<Chat>) {
+ for message in reader.read() {
+ chat.messages.push(
+ format!("{}: {}", message.actor, message.content)
+ );
+ }
+}
+
+pub fn handle_existing_players_list(mut reader: EventReader<PlayerListPacket>, mut commands: Commands) {
+ for packet in reader.read() {
+ for (server_id, username) in &packet.players {
+ commands.spawn(OtherPlayerBundle {
+ part: PartBundle {
+ transform: Transform {
+ translation: Translation3::new(0.0, 0.0, 0.0),
+ rotation: Rotation2::new(0.0),
+ scale: Scale3::new(25.0, 25.0, 1.0)
+ },
+ texture: Texture {
+ name: "hearty.svg".to_string()
+ },
+ server_id: ServerId(*server_id),
+ part: Part(false),
+ },
+ username: PlayerUsername {
+ username: username.clone()
+ }
+ });
+ }
+ }
+}
+
+pub fn handle_spawn_player(mut reader: EventReader<SpawnPlayerPacket>, mut commands: Commands) {
+ for SpawnPlayerPacket { id: server_id, username } in reader.read() {
+ commands.spawn(OtherPlayerBundle {
+ part: PartBundle {
+ transform: Transform {
+ translation: Translation3::new(0.0, 0.0, 0.0),
+ rotation: Rotation2::new(0.0),
+ scale: Scale3::new(25.0, 25.0, 1.0)
+ },
+ texture: Texture {
+ name: "hearty.svg".to_string()
+ },
+ server_id: ServerId(*server_id),
+ part: Part(false),
+ },
+ username: PlayerUsername {
+ username: username.clone()
+ }
+ });
+ }
+}
+
+pub fn handle_spawn_part(mut reader: EventReader<SpawnPartPacket>, mut commands: Commands) {
+ for SpawnPartPacket { id: server_id, part } in reader.read() {
+ commands.spawn(PartBundle {
+ transform: Transform {
+ translation: Translation3::new(part.transform.x, part.transform.y, 0.0),
+ rotation: Rotation2::new(part.transform.rot),
+ scale: Scale3::new(25.0, 25.0, 1.0),
+ },
+ texture: Texture {
+ name: texture_name(part.part_type, part.flags.attached),
+ },
+ server_id: ServerId(*server_id),
+ part: Part(part.flags.attached),
+ });
+ }
+}
+
+pub fn handle_part_positions(mut reader: EventReader<PartPositionsPacket>, mut parts_query: Query<(Entity, &ServerId, &mut Transform, &mut Texture, &mut Part)>, mut player: Query<&ServerId, With<Player>>, mut camera: ResMut<Camera>) {
+ for PartPositionsPacket { parts } in reader.read() {
+ for (this_id, part) in parts {
+ for (_, server_id, mut transform, mut texture, mut bevy_part) in &mut parts_query {
+ if *this_id == server_id.0 {
+ transform.translation.x = part.transform.x;
+ transform.translation.y = part.transform.y;
+ transform.rotation = Rotation2::new(part.transform.rot);
+
+ if part.flags.attached && !bevy_part.0 {
+ texture.name = texture_name(part.part_type, part.flags.attached);
+ bevy_part.0 = true;
+ } else if !part.flags.attached && bevy_part.0 {
+ texture.name = texture_name(part.part_type, part.flags.attached);
+ bevy_part.0 = false;
+ }
+ }
+
+ if part.part_type == PartType::Hearty {
+ let player_id = player.single();
+ if player_id.0 == server_id.0 {
+ camera.x = -part.transform.x;
+ camera.y = -part.transform.y;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+pub fn handle_energy_update(mut reader: EventReader<EnergyUpdatePacket>, mut player_res: ResMut<PlayerResources>) {
+ for EnergyUpdatePacket { amount, max } in reader.read() {
+ player_res.fuel_amount = *amount;
+ player_res.fuel_max = *max;
+ }
+}
+
+pub fn handle_crafting_ui(mut reader: EventReader<OpenCraftingUiPacket>, entities: Query<(Entity, &ServerId)>, mut commands: Commands) {
+ for OpenCraftingUiPacket { id } in reader.read() {
+ for (entity, server_id) in &entities {
+ if server_id.0 == *id {
+ commands.entity(entity)
+ .insert(Menu);
+ }
+ }
+ }
+}
+
+pub fn handle_player_leave(mut reader: EventReader<PlayerLeavePacket>, mut part_query: Query<(Entity, &ServerId), With<Part>>, mut commands: Commands) {
+ for PlayerLeavePacket { id } in reader.read() {
+ for (entity, server_id) in &mut part_query {
+ if server_id.0 == *id {
+ commands.entity(entity).despawn();
+ }
+ }
+ }
+}
+
+pub fn handle_despawn_part(mut reader: EventReader<DespawnPartPacket>, mut part_query: Query<(Entity, &ServerId), With<Part>>, mut commands: Commands) {
+ for DespawnPartPacket { id } in reader.read() {
+ for (entity, server_id) in &mut part_query {
+ if server_id.0 == *id {
+ commands.entity(entity).despawn();
+ }
+ }
+ }
+}<
\ No newline at end of file
M crates/client/src/networking/mod.rs => crates/client/src/networking/mod.rs +28 -202
@@ 10,19 10,17 @@ use bevy_ecs::{
query::{QuerySingleError, With},
world::World,
};
+use bevy_ecs::prelude::Event;
use nalgebra::{Rotation2, Scale3, Translation3};
use starkingdoms_common::packet::Packet::{
DespawnPart, EnergyUpdate, LoginResponse, Message, OpenCraftingUi, PartPositions,
PlanetPositions, PlayerLeave, PlayerList, SpawnPart, SpawnPlayer,
};
-use starkingdoms_common::packet::{
- DespawnPartPacket, EnergyUpdatePacket, LoginResponsePacket, MessagePacket,
- OpenCraftingUiPacket, PartPositionsPacket, PlanetPositionsPacket, PlayerLeavePacket,
- PlayerListPacket, SpawnPartPacket, SpawnPlayerPacket,
-};
+use starkingdoms_common::packet::{DespawnPartPacket, EnergyUpdatePacket, LoginResponsePacket, MessagePacket, OpenCraftingUiPacket, Packet, PartPositionsPacket, PlanetPositionsPacket, PlayerLeavePacket, PlayerListPacket, SpawnPartPacket, SpawnPlayerPacket};
use starkingdoms_common::{PartType, PlanetType};
pub mod websocket;
+pub mod handlers;
fn texture_name(part_type: PartType, attached: bool) -> String {
use PartType::*;
@@ 49,203 47,31 @@ fn texture_name(part_type: PartType, attached: bool) -> String {
}
}
-pub fn process_packets(
- world: &mut World,
- _send_packet_events: &mut Events<SendPacket>,
- recv_packet_events: &mut Events<RecvPacket>,
- planet_types: &mut HashMap<PlanetType, (Entity, u32)>,
-) {
- let mut recv_cursor = recv_packet_events.get_cursor();
- for recv in recv_cursor.read(recv_packet_events) {
- match &recv.0 {
- LoginResponse(LoginResponsePacket { id }) => {
- let mut player_query = world.query_filtered::<Entity, With<Player>>();
- let entity = player_query.single(world);
- world.entity_mut(entity).insert(ServerId(*id));
- }
- PlayerList(PlayerListPacket { players }) => {
- // existing players
- // username sync, eventually
- for player in players {
- world.spawn((
- Transform {
- translation: Translation3::new(0.0, 0.0, 0.0),
- rotation: Rotation2::new(0.0),
- scale: Scale3::new(25.0, 25.0, 1.0),
- },
- Texture {
- name: "hearty.svg".to_string(),
- },
- ServerId(player.0),
- Part(false),
- ));
- }
- }
- SpawnPlayer(SpawnPlayerPacket { id, .. }) => {
- // username sync, eventually
- world.spawn((
- Transform {
- translation: Translation3::new(0.0, 0.0, 0.0),
- rotation: Rotation2::new(0.0),
- scale: Scale3::new(25.0, 25.0, 1.0),
- },
- Texture {
- name: "hearty.svg".to_string(),
- },
- ServerId(*id),
- Part(false),
- ));
- }
- SpawnPart(SpawnPartPacket { id, part }) => {
- world.spawn((
- Transform {
- translation: Translation3::new(part.transform.x, part.transform.y, 0.0),
- rotation: Rotation2::new(part.transform.rot),
- scale: Scale3::new(25.0, 25.0, 1.0),
- },
- Texture {
- name: texture_name(part.part_type, part.flags.attached),
- },
- ServerId(*id),
- Part(part.flags.attached),
- ));
- }
- PartPositions(PartPositionsPacket { parts }) => {
- for (id, part) in parts {
- if part.part_type == PartType::Hearty {
- let mut player_query = world.query_filtered::<&ServerId, With<Player>>();
- let server_id = match player_query.get_single(world) {
- Ok(player) => player,
- Err(e) => match e {
- QuerySingleError::NoEntities(_) => {
- continue;
- }
- QuerySingleError::MultipleEntities(_) => {
- panic!("There should never multiple players marked as players");
- }
- },
- };
- if server_id.0 == *id {
- let mut camera = world.resource_mut::<Camera>();
- camera.x = -part.transform.x;
- camera.y = -part.transform.y;
- }
- }
- let mut part_query =
- world
- .query::<(Entity, &ServerId, &mut Transform, &mut Texture, &mut Part)>(
- );
- for (_, server_id, mut transform, mut texture, mut bevy_part) in
- part_query.iter_mut(world)
- {
- if server_id.0 == *id {
- transform.translation.x = part.transform.x;
- transform.translation.y = part.transform.y;
- transform.rotation = Rotation2::new(part.transform.rot);
+pub fn send_event<T: Event>(e: T, world: &mut World) {
+ let mut events = world.resource_mut::<Events<T>>();
+ events.send(e);
+}
- if part.flags.attached && !bevy_part.0 {
- texture.name = texture_name(part.part_type, part.flags.attached);
- bevy_part.0 = true;
- } else if !part.flags.attached && bevy_part.0 {
- texture.name = texture_name(part.part_type, part.flags.attached);
- bevy_part.0 = false;
- }
- }
- }
- }
- }
- PlanetPositions(PlanetPositionsPacket { planets }) => {
- for (server_id, planet) in planets {
- planet_types.entry(planet.planet_type).or_insert_with(|| {
- let entity = world.spawn(SpriteBundle {
- transform: Transform {
- translation: Translation3::new(
- planet.transform.x,
- planet.transform.y,
- 0.0,
- ),
- rotation: Rotation2::new(planet.transform.rot),
- scale: Scale3::new(planet.radius, planet.radius, 1.0),
- },
- texture: Texture {
- name: match planet.planet_type {
- /*PlanetType::Sun => "sun.svg",
- PlanetType::Mercury => "mercury.svg",
- PlanetType::Venus => "venus.svg",
- PlanetType::Earth => "earth.svg",
- PlanetType::Moon => "moon.svg",
- PlanetType::Mars => "mars.svg",
- PlanetType::Jupiter => "jupiter.svg",
- PlanetType::Saturn => "saturn.svg",
- PlanetType::Uranus => "uranus.svg",
- PlanetType::Neptune => "neptune.svg",
- PlanetType::Pluto => "pluto.svg",*/
- PlanetType::Sun => "sun.svg",
- PlanetType::Mercury => "moon.svg",
- PlanetType::Venus => "venus.svg",
- PlanetType::Earth => "earth.svg",
- PlanetType::Moon => "moon.svg",
- PlanetType::Mars => "mars.svg",
- PlanetType::Jupiter => "jupiter.svg",
- PlanetType::Saturn => "sun.svg",
- PlanetType::Uranus => "venus.svg",
- PlanetType::Neptune => "mars.svg",
- PlanetType::Pluto => "earth.svg",
- }
- .to_string(),
- },
- });
- (entity.id(), *server_id)
- });
- }
- }
- EnergyUpdate(EnergyUpdatePacket { amount, max }) => {
- let mut r = world.resource_mut::<PlayerResources>();
- r.fuel_amount = *amount;
- r.fuel_max = *max;
- }
- OpenCraftingUi(OpenCraftingUiPacket { id }) => {
- let mut query = world.query::<(Entity, &ServerId)>();
- let mut matching_id = None;
- for (entity, server_id) in query.iter(world) {
- if server_id.0 == *id {
- matching_id = Some(entity);
- }
- }
- if let Some(id) = matching_id {
- world.entity_mut(id).insert(Menu);
- }
- }
- Message(MessagePacket { actor, content, .. }) => {
- let mut chat = world.get_resource_mut::<Chat>().unwrap();
- chat.messages
- .push(format!("{}: {}", actor.clone(), content.clone()));
- }
- PlayerLeave(PlayerLeavePacket { id }) => {
- let mut part_query = world.query_filtered::<(Entity, &ServerId), With<Part>>();
- let mut entity_to_remove = None;
- for (entity, server_id) in part_query.iter_mut(world) {
- if server_id.0 == *id {
- entity_to_remove = Some(entity);
- }
- }
- if let Some(entity) = entity_to_remove {
- world.despawn(entity);
- }
- }
- DespawnPart(DespawnPartPacket { id }) => {
- let mut part_query = world.query_filtered::<(Entity, &ServerId), With<Part>>();
- let mut entity_to_remove = None;
- for (entity, server_id) in part_query.iter_mut(world) {
- if server_id.0 == *id {
- entity_to_remove = Some(entity);
- }
- }
- if let Some(entity) = entity_to_remove {
- world.despawn(entity);
- }
- }
- _ => {}
- }
+pub fn send_packet_event(packet: Packet, world: &mut World) {
+ match packet {
+ Packet::ClientLogin(e) => send_event(e, world),
+ Packet::SendMessage(e) => send_event(e, world),
+ Packet::PlayerInput(e) => send_event(e, world),
+ Packet::PlayerMouseInput(e) => send_event(e, world),
+ Packet::RequestSave(e) => send_event(e, world),
+ Packet::_SpecialDisconnect(e) => send_event(e, world),
+ LoginResponse(e) => send_event(e, world),
+ SpawnPlayer(e) => send_event(e, world),
+ PlayerList(e) => send_event(e, world),
+ PlanetPositions(e) => send_event(e, world),
+ PartPositions(e) => send_event(e, world),
+ SpawnPart(e) => send_event(e, world),
+ DespawnPart(e) => send_event(e, world),
+ PlayerLeave(e) => send_event(e, world),
+ Message(e) => send_event(e, world),
+ Packet::SaveEligibility(e) => send_event(e, world),
+ Packet::SaveData(e) => send_event(e, world),
+ EnergyUpdate(e) => send_event(e, world),
+ OpenCraftingUi(e) => send_event(e, world),
}
}
M crates/client/src/rendering/mod.rs => crates/client/src/rendering/mod.rs +13 -10
@@ 34,12 34,13 @@ use winit::{
};
use crate::components::{Camera, Menu, RecvPacket, SendPacket};
-use crate::networking::process_packets;
+use crate::networking::send_packet_event;
use crate::networking::websocket::Websocket;
use crate::platform::websocket::Ws;
use crate::rendering::renderer::{RenderCreateContext, Renderer};
use crate::rendering::MaybeRenderer::{Initialized, Initializing};
use assets::AssetLoader;
+use crate::components::Schedule::Update;
pub mod assets;
mod renderer;
@@ 402,28 403,30 @@ impl ApplicationHandler for App {
};
let Some(window) = &self.window else { return };
- let ws = self
+ let mut ws = self
.world
.get_resource_mut::<Ws>()
.expect("Failed to get Ws resource");
+
+ let mut packets = vec![];
+
#[cfg(target_arch = "wasm32")]
while let Ok(Some(packet)) = ws.receiver.try_next() {
- renderer.recv_packet_events.send(RecvPacket(packet));
+ packets.push(packet);
}
#[cfg(not(target_arch = "wasm32"))]
while let Ok(packet) = ws.receiver.try_recv() {
- renderer.recv_packet_events.send(RecvPacket(packet));
+ packets.push(packet);
+ }
+
+ for packet in packets {
+ send_packet_event(packet, &mut self.world);
}
renderer.send_packet_events.update();
renderer.recv_packet_events.update();
- process_packets(
- &mut self.world,
- &mut renderer.send_packet_events,
- &mut renderer.recv_packet_events,
- &mut renderer.planet_types,
- );
+ self.world.run_schedule(Update);
let gl = self.gl.as_ref().unwrap();
unsafe {
A crates/client/src/systems.rs => crates/client/src/systems.rs +21 -0
@@ 0,0 1,21 @@
+use bevy_ecs::bundle::Bundle;
+use bevy_ecs::prelude::Commands;
+use nalgebra::{Rotation2, Scale3, Translation3};
+use crate::components::{Part, Player, PlayerBundle, Texture, Transform};
+
+
+
+pub fn create_hearty(mut commands: Commands) {
+ commands.spawn(PlayerBundle {
+ transform: Transform {
+ translation: Translation3::new(0.0, 0.0, 0.0),
+ rotation: Rotation2::new(0.0),
+ scale: Scale3::new(25.0, 25.0, 1.0),
+ },
+ texture: Texture {
+ name: "hearty.svg".to_string(),
+ },
+ player: Player,
+ part: Part(false)
+ });
+}<
\ No newline at end of file
M crates/common/Cargo.toml => crates/common/Cargo.toml +5 -0
@@ 12,3 12,8 @@ rmp-serde = "1"
hmac = "0.12"
sha2 = "0.10"
base64 = "0.21"
+bevy_ecs = { version = "0.15", optional = true }
+
+[features]
+default = []
+bevy = ["dep:bevy_ecs"]<
\ No newline at end of file
M crates/common/src/packet.rs => crates/common/src/packet.rs +43 -1
@@ 77,17 77,20 @@ pub enum ButtonType {
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct ClientLoginPacket {
pub username: String,
pub save: Option<String>,
pub jwt: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct SendMessagePacket {
pub target: Option<String>,
pub content: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct PlayerInputPacket {
pub up: bool,
pub down: bool,
@@ 96,6 99,7 @@ pub struct PlayerInputPacket {
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct PlayerMouseInputPacket {
pub x: f32,
pub y: f32,
@@ 104,56 108,67 @@ pub struct PlayerMouseInputPacket {
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct RequestSavePacket {
pub old_save: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct SpecialDisconnectPacket {}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct LoginResponsePacket {
pub id: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct SpawnPlayerPacket {
pub id: u32,
pub username: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct PlayerListPacket {
pub players: Vec<(u32, String)>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct PlanetPositionsPacket {
pub planets: Vec<(u32, Planet)>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct PartPositionsPacket {
pub parts: Vec<(u32, Part)>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct SpawnPartPacket {
pub id: u32,
pub part: Part,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct DespawnPartPacket {
pub id: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct PlayerLeavePacket {
pub id: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct MessagePacket {
pub message_type: MessageType,
pub actor: String,
@@ 161,22 176,26 @@ pub struct MessagePacket {
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct SaveEligibilityPacket {
pub eligible: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct SaveDataPacket {
pub payload: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct EnergyUpdatePacket {
pub amount: u32,
pub max: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
+#[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))]
pub struct OpenCraftingUiPacket {
pub id: u32,
}
@@ 208,6 227,29 @@ pub enum Packet {
OpenCraftingUi(OpenCraftingUiPacket),
}
+#[cfg(feature = "bevy")]
+pub fn register_packet_events(world: &mut bevy_ecs::prelude::World) {
+ bevy_ecs::event::EventRegistry::register_event::<ClientLoginPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<SendMessagePacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<PlayerInputPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<PlayerMouseInputPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<RequestSavePacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<SpecialDisconnectPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<LoginResponsePacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<PlayerListPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<PlanetPositionsPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<PartPositionsPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<SpawnPartPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<DespawnPartPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<MessagePacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<SaveEligibilityPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<SaveDataPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<EnergyUpdatePacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<OpenCraftingUiPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<SpawnPlayerPacket>(world);
+ bevy_ecs::event::EventRegistry::register_event::<PlayerLeavePacket>(world);
+}
+
impl From<Packet> for String {
fn from(val: Packet) -> Self {
serde_json::to_string(&val).expect("failed to serialize packet to json")
@@ 238,4 280,4 @@ impl TryFrom<&Vec<u8>> for Packet {
fn try_from(value: &Vec<u8>) -> Result<Self, Self::Error> {
serde_json::from_slice(value).map_err(MsgFromError::JSONError)
}
-}
+}<
\ No newline at end of file