From b13d8b9b2bf3ce194c60aaede8450d9f03744f30 Mon Sep 17 00:00:00 2001 From: ghostlyzsh Date: Sun, 7 Jan 2024 10:45:45 -0600 Subject: [PATCH] loading but rust is angry --- server/src/component.rs | 14 +- server/src/main.rs | 354 ++++++++++++++++++++++++--------- starkingdoms-common/src/lib.rs | 20 +- 3 files changed, 281 insertions(+), 107 deletions(-) diff --git a/server/src/component.rs b/server/src/component.rs index 755da78d8e3504555bc0acf8b71482329313bce6..16af1358dce91fdd5450e1f357bbc9037ac73028 100644 --- a/server/src/component.rs +++ b/server/src/component.rs @@ -35,7 +35,7 @@ pub enum PartType { LandingThruster, LandingThrusterSuspension, } -impl From for starkingdoms_common::PartType { +impl From for c_PartType { fn from(value: PartType) -> Self { match value { PartType::Placeholder => c_PartType::Placeholder, @@ -47,6 +47,18 @@ impl From for starkingdoms_common::PartType { } } } +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, + } + } +} #[derive(Component, Clone, Debug)] pub struct Attach { diff --git a/server/src/main.rs b/server/src/main.rs index 2dbc4e371c606a08bf66e345b5ad56c652392ebe..9e1b66f9ca1b267d9f549390fa02c0601c895103 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -79,7 +79,7 @@ fn main() { .add_systems(Startup, setup_integration_parameters) .add_systems(Startup, spawn_planets) .add_systems(FixedUpdate, module_spawn) - .add_systems(Update, on_message) + .add_systems(Update, (on_message, on_login).chain()) .add_systems(Update, on_close) .add_systems(FixedUpdate, on_position_change) .add_systems( @@ -212,41 +212,12 @@ fn module_spawn( } } -fn on_message( - mut commands: Commands, - planet_query: Query<(Entity, &PlanetType, &Transform)>, - mut part_query: Query< - ( - Entity, - &PartType, - &mut Transform, - &mut Velocity, - Option<&LooseAttach>, - &mut PartFlags, - ), - (Without, Without, Without), - >, - mut attached_query: Query< - ( - Entity, - &PartType, - &mut Transform, - &mut Attach, - &Velocity, - Option<&CanAttach>, - Option<&LooseAttach>, - &mut PartFlags, - ), - (Without, Without), - >, - mut player_query: Query< - (Entity, &mut Player, &Transform, &Velocity, &mut Attach), - Without, - >, +fn on_login( + world: &mut World, mut packet_recv: Local>, - mut packet_event_send: ResMut>, - app_keys: Res, + mut packet_event_send: Local>, ) { + let app_keys = world.resource::().clone(); let mut event_queue = Vec::new(); for ev in packet_recv.read(&packet_event_send) { if let ServerEvent::Recv(addr, MessageType::Text, data) = ev { @@ -255,24 +226,6 @@ fn on_message( match packet { Packet::ClientLogin { username, save } => { - if let Some(save) = save { - // attempt to decode the savefile - if let Ok(savefile) = unpack_savefile(&app_keys.app_key, save) { - // HEY! GHOSTLY! THIS SAVE FILE IS VALID! PLEASE LOAD IT! - // THANKS! - } else { - let packet = Packet::Message { - message_type: packet::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(), - }; - let buf = serde_json::to_vec(&packet).unwrap(); - event_queue.push(ServerEvent::Send(*addr, MessageType::Text, buf)); - } - } else { - // nothing to do - } - let angle: f32 = { let mut rng = rand::thread_rng(); rng.gen::() * std::f32::consts::PI * 2. @@ -283,7 +236,7 @@ fn on_message( 0.0, ); transform.rotate_z(angle); - let entity_id = commands + let mut entity_id = world .spawn(PlayerBundle { part: PartBundle { part_type: PartType::Hearty, @@ -302,8 +255,8 @@ fn on_message( parent: None, children: [None, None, None, None], }, - }) - .insert(Collider::cuboid( + }); + entity_id.insert(Collider::cuboid( PART_HALF_SIZE / SCALE, PART_HALF_SIZE / SCALE, )) @@ -319,13 +272,14 @@ fn on_message( .insert(ExternalForce::default()) .insert(ReadMassProperties::default()) .insert(Velocity::default()) - .insert(RigidBody::Dynamic) - .id(); - let id = entity_id.index(); + .insert(RigidBody::Dynamic); + let id = entity_id.id().index(); + + let mut planet_query = world.query::<(Entity, &PlanetType, &Transform)>(); // tell this player the planets let mut planets = Vec::new(); - for (entity, planet_type, transform) in planet_query.iter() { + for (entity, planet_type, transform) in planet_query.iter(&world) { let translation = transform.translation; planets.push(( entity.index(), @@ -347,8 +301,9 @@ fn on_message( event_queue.push(ServerEvent::Send(*addr, MessageType::Text, buf)); // tell the player already existing users + let mut player_query = world.query_filtered::<(Entity, &mut Player, &Transform, &Velocity, &mut Attach), Without>(); let mut players = Vec::new(); - for (entity, player, _, _, _) in &player_query { + for (entity, player, _, _, _) in player_query.iter(&world) { players.push((entity.index(), player.username.clone())); } let packet = Packet::PlayerList { players }; @@ -371,8 +326,11 @@ fn on_message( event_queue.push(ServerEvent::Broadcast(MessageType::Text, buf)); // tell the player where parts are + let mut part_query = world.query_filtered::<(Entity, &PartType, &mut Transform, &mut Velocity, + Option<&LooseAttach>, &mut PartFlags), + (Without, Without, Without)>(); let mut parts = Vec::new(); - for (entity, part_type, transform, _, _, flags) in &part_query { + for (entity, part_type, transform, _, _, flags) in part_query.iter(&world) { parts.push(( entity.index(), Part { @@ -384,7 +342,10 @@ fn on_message( }, )); } - for (entity, part_type, transform, _, _, _, _, flags) in &attached_query { + let mut attached_query = world.query_filtered::<(Entity, &PartType, &mut Transform, + &mut Attach, &Velocity, Option<&CanAttach>, Option<&LooseAttach>, &mut PartFlags), + (Without, Without)>(); + for (entity, part_type, transform, _, _, _, _, flags) in attached_query.iter(&world) { parts.push(( entity.index(), Part { @@ -419,47 +380,241 @@ fn on_message( }; let buf = serde_json::to_vec(&packet).unwrap(); event_queue.push(ServerEvent::Send(*addr, MessageType::Text, buf)); - } - Packet::SendMessage { target, content } => { - // find our player - let mut player = None; - for (_, q_player, _, _, _) in &player_query { - if q_player.addr == *addr { - player = Some(q_player); - } - } - let player = player.unwrap(); - if let Some(target_username) = target { - let mut target_player = None; - for (_, q_player, _, _, _) in &player_query { - if q_player.username == target_username { - target_player = Some(q_player); - } + if let Some(save) = save { + // attempt to decode the savefile + if let Ok(savefile) = unpack_savefile(&app_keys.app_key, save) { + // HEY! GHOSTLY! THIS SAVE FILE IS VALID! PLEASE LOAD IT! + // THANKS! + let mut attach = entity_id.get_mut::().unwrap(); + load_savefile(world, transform, entity_id.id(), entity_id.id(), &mut attach, savefile.children, &mut attached_query, &mut part_query); + } else { + let packet = Packet::Message { + message_type: packet::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(), + }; + let buf = serde_json::to_vec(&packet).unwrap(); + event_queue.push(ServerEvent::Send(*addr, MessageType::Text, buf)); } - let target_player = target_player.unwrap(); - let packet = Packet::Message { - message_type: packet::MessageType::Direct, - actor: player.username.clone(), - content, - }; - let buf = serde_json::to_vec(&packet).unwrap(); - event_queue.push(ServerEvent::Send( - target_player.addr, - MessageType::Text, - buf.clone(), - )); - event_queue.push(ServerEvent::Send(*addr, MessageType::Text, buf)); } else { - // send to general chat - let packet = Packet::Message { - message_type: packet::MessageType::Chat, - actor: player.username.clone(), - content, - }; - let buf = serde_json::to_vec(&packet).unwrap(); - event_queue.push(ServerEvent::Broadcast(MessageType::Text, buf)); + // nothing to do } } + _ => {} + } + } + } + for event in event_queue { + packet_event_send.send(event); + } +} + +fn load_savefile( + world: &mut World, + transform: Transform, + player_id: Entity, + parent: Entity, + parent_attach: &mut Attach, + children: Vec>, + attached_query: &mut QueryState< + ( + Entity, + &PartType, + &mut Transform, + &mut Attach, + &Velocity, + Option<&CanAttach>, + Option<&LooseAttach>, + &mut PartFlags, + ), + (Without, Without), + >, + part_query: &mut QueryState< + ( + Entity, + &PartType, + &mut Transform, + &mut Velocity, + Option<&LooseAttach>, + &mut PartFlags, + ), + (Without, Without, Without), + >, +) -> bool { + let mut ret = false; + for (i, child) in children.iter().enumerate() { + if let Some(child) = child { + //let attachable = can_attach != None; + + let p_pos = transform.translation; + let angle = transform.rotation.to_euler(EulerRot::ZYX).0; + let mut offset = Vec2::ZERO; + let mut angle_offset = 0.; + if i == 2 { + offset = Vec2::new(53., -53.); + angle_offset = 0.; + } else if i == 0 { + offset = Vec2::new(-53., 53.); + angle_offset = PI; + } else if i == 1 { + offset = Vec2::new(53., 53.); + angle_offset = PI / 2.; + } else if i == 3 { + offset = Vec2::new(-53., -53.); + angle_offset = -PI / 2.; + } + let mut module = world.spawn(PartBundle { + transform: TransformBundle::from(Transform::from_xyz( + p_pos.x + offset.x / SCALE * angle.cos(), + p_pos.y + offset.y / SCALE * angle.sin(), + 0., + ).with_rotation(Quat::from_euler(EulerRot::ZYX, angle + angle_offset, 0., 0.))), + part_type: child.part_type.into(), + flags: PartFlags { attached: true }, + }); + module.insert(RigidBody::Dynamic) + .with_children(|children| { + children + .spawn(Collider::cuboid(18.75 / SCALE, 23.4375 / SCALE)) + .insert(TransformBundle::from(Transform::from_xyz( + 0., + 1.5625 / SCALE, + 0., + ))); + }) + .insert(AdditionalMassProperties::MassProperties(MassProperties { + local_center_of_mass: vec2(0.0, 0.0), + mass: 0.0001, + principal_inertia: 0.005, + })) + .insert(ExternalForce::default()) + .insert(ExternalImpulse::default()) + .insert(Velocity::default()) + .insert(ReadMassProperties::default()); + let joint = FixedJointBuilder::new() + .local_anchor1(vec2(-53. / SCALE, 0. / SCALE)) + .local_basis2(-PI / 2.); + let mut children = [None, None, None, None]; + if PartType::from(child.part_type) == PartType::LandingThruster { + module.insert(Attach { + associated_player: Some(player_id), + parent: Some(module.id()), + children: [None, None, None, None], + }); + let joint = PrismaticJointBuilder::new(Vec2::new(0., 1.)) + .local_anchor1(Vec2::new(0., 0.)) + .local_anchor2(Vec2::new(0., 0.)) + .motor_position(0., 150., 10.) + .limits([0., 50. / SCALE]) + .build(); + let mut suspension = world.spawn(PartBundle { + transform: TransformBundle::from(Transform::from_xyz( + p_pos.x + offset.x / SCALE * angle.cos(), + p_pos.y + offset.y / SCALE * angle.sin(), + 0., + ).with_rotation(Quat::from_euler(EulerRot::ZYX, angle + angle_offset, 0., 0.))), + part_type: PartType::LandingThrusterSuspension, + flags: PartFlags { attached: false }, + }); + suspension + .insert(RigidBody::Dynamic) + .with_children(|children| { + children + .spawn(Collider::cuboid(PART_HALF_SIZE / SCALE, 1. / SCALE)) + .insert(TransformBundle::from(Transform::from_xyz( + 0., + -24. / SCALE, + 0., + ))); + }) + .insert(ImpulseJoint::new(module.id(), joint)) + .insert(ExternalForce::default()) + .insert(ExternalImpulse::default()) + .insert(Velocity::default()) + .insert(ReadMassProperties::default()) + .insert(AdditionalMassProperties::MassProperties(MassProperties { + local_center_of_mass: vec2(0.0, 0.0), + mass: 0.00000000000001, + principal_inertia: 0.0000000000001, + })) + .insert(Attach { + associated_player: Some(player_id), + parent: Some(module.id()), + children: [None, None, None, None], + }); + children[2] = Some(suspension.id()); + } + module.insert(ImpulseJoint::new(parent, joint)); + module.insert(Attach { + associated_player: Some(player_id), + parent: Some(parent), + children, + }); + parent_attach.children[i] = Some(module.id()); + //module.5.attached = true; + + ret = ret + | if PartType::from(child.part_type) != PartType::LandingThruster { + load_savefile( + world, + transform, + player_id, + module.id(), + &mut module.get_mut::().unwrap(), + child.children.clone(), + attached_query, + part_query, + ) + } else { + false + }; + } + } + return ret; +} + +fn on_message( + mut commands: Commands, + planet_query: Query<(Entity, &PlanetType, &Transform)>, + mut part_query: Query< + ( + Entity, + &PartType, + &mut Transform, + &mut Velocity, + Option<&LooseAttach>, + &mut PartFlags, + ), + (Without, Without, Without), + >, + mut attached_query: Query< + ( + Entity, + &PartType, + &mut Transform, + &mut Attach, + &Velocity, + Option<&CanAttach>, + Option<&LooseAttach>, + &mut PartFlags, + ), + (Without, Without), + >, + mut player_query: Query< + (Entity, &mut Player, &Transform, &Velocity, &mut Attach), + Without, + >, + mut packet_recv: Local>, + mut packet_event_send: ResMut>, + app_keys: Res, +) { + let mut event_queue = Vec::new(); + for ev in packet_recv.read(&packet_event_send) { + if let ServerEvent::Recv(addr, MessageType::Text, data) = ev { + let data = String::from_utf8_lossy(&data); + let packet: Packet = err_or_cont!(serde_json::from_str(&data)); + + match packet { Packet::PlayerInput { up, down, @@ -911,6 +1066,7 @@ fn on_message( } } + fn construct_save_data( attach: Attach, attached_query: &Query< diff --git a/starkingdoms-common/src/lib.rs b/starkingdoms-common/src/lib.rs index 3145e511cf3fbeaa8ccaf8a24eeacb8f481b214e..6608d51e25e73fdf600215fc6fed030cea436816 100644 --- a/starkingdoms-common/src/lib.rs +++ b/starkingdoms-common/src/lib.rs @@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize}; use sha2::Sha256; use std::error::Error; -#[derive(Serialize, Deserialize, Debug)] +#[derive(Clone, Serialize, Deserialize, Debug)] pub struct SaveData { // ---------------------------------------------------------------------- // HEY YOU @@ -32,7 +32,7 @@ pub struct SaveData { pub children: Vec>, } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Clone, Serialize, Deserialize, Debug)] pub struct SaveModule { pub part_type: PartType, pub children: Vec>, @@ -73,15 +73,21 @@ pub fn pack_savefile(key: &str, save_data: SaveData) -> String { } pub fn unpack_savefile(key: &str, file: String) -> Result> { // << reverse! << - let savefile_bytes = base64::engine::general_purpose::STANDARD.decode(file).map_err(|e| format!("error decoding b64: {e}"))?; + let savefile_bytes = base64::engine::general_purpose::STANDARD + .decode(file) + .map_err(|e| format!("error decoding b64: {e}"))?; - let save_file: Savefile = rmp_serde::from_slice(&savefile_bytes).map_err(|e| format!("error decoding savefile wrapper: {e}"))?; + let save_file: Savefile = rmp_serde::from_slice(&savefile_bytes) + .map_err(|e| format!("error decoding savefile wrapper: {e}"))?; - let mut mac: Hmac = Hmac::new_from_slice(key.as_bytes()).map_err(|e| format!("error loading hmac-sha256: {e}"))?; + let mut mac: Hmac = Hmac::new_from_slice(key.as_bytes()) + .map_err(|e| format!("error loading hmac-sha256: {e}"))?; mac.update(&save_file.data_msgpack); - mac.verify_slice(&save_file.mac).map_err(|e| format!("error verifying signature: {e}"))?; + mac.verify_slice(&save_file.mac) + .map_err(|e| format!("error verifying signature: {e}"))?; - let save_data = rmp_serde::from_slice(&save_file.data_msgpack).map_err(|e| format!("error decoding inner signature: {e}"))?; + let save_data = rmp_serde::from_slice(&save_file.data_msgpack) + .map_err(|e| format!("error decoding inner signature: {e}"))?; Ok(save_data) }