From 79b5eba89ef3fcf1e1ce8c9d1d8b47c01d3f854e Mon Sep 17 00:00:00 2001 From: ghostlyzsh Date: Sun, 7 Jan 2024 11:20:48 -0600 Subject: [PATCH] broken save before changes --- server/src/main.rs | 586 +++++++++++++++++++-------------------------- 1 file changed, 244 insertions(+), 342 deletions(-) diff --git a/server/src/main.rs b/server/src/main.rs index a13a68ec80c944f2b023b833667796d67e0dd477..0cb021f5fa6721d9650cafe995706d128090a7a1 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -24,16 +24,11 @@ use bevy_rapier2d::prelude::*; use bevy_twite::{twite::frame::MessageType, ServerEvent, TwiteServerConfig, TwiteServerPlugin}; use component::Input; use component::*; -use hmac::{Hmac, Mac}; -use jwt::VerifyWithKey; use packet::*; use rand::Rng; -use serde::{Deserialize, Serialize}; -use sha2::Sha256; use starkingdoms_common::SaveModule; use starkingdoms_common::{pack_savefile, unpack_savefile, SaveData}; use std::f32::consts::PI; -use std::time::SystemTime; pub mod component; pub mod macros; @@ -61,10 +56,10 @@ const FREE_MODULE_CAP: usize = 30; fn main() { // read the key in - let key = std::fs::read("/etc/starkingdoms/app_key").unwrap(); + let key = std::fs::read_to_string("/etc/starkingdoms/app_key").unwrap(); App::new() - .insert_resource(AppKeys { app_key: key }) + .insert_resource(AppKeys { app_key: key.into_bytes() }) .insert_resource(TwiteServerConfig { addr: Ipv4Addr::new(0, 0, 0, 0), port: 3000, @@ -84,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, on_login).chain()) + .add_systems(Update, on_message) .add_systems(Update, on_close) .add_systems(FixedUpdate, on_position_change) .add_systems( @@ -217,12 +212,41 @@ fn module_spawn( } } -fn on_login( - world: &mut World, +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: Local>, + mut packet_event_send: ResMut>, + app_keys: Res, ) { - 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 { @@ -231,6 +255,7 @@ fn on_login( match packet { Packet::ClientLogin { username, save, jwt } => { + let angle: f32 = { let mut rng = rand::thread_rng(); rng.gen::() * std::f32::consts::PI * 2. @@ -241,26 +266,26 @@ fn on_login( 0.0, ); transform.rotate_z(angle); - let mut entity_id = world.spawn(PlayerBundle { - part: PartBundle { - part_type: PartType::Hearty, - transform: TransformBundle::from(transform), - flags: PartFlags { attached: false }, - }, - player: Player { - addr: *addr, - username: username.to_string(), - input: component::Input::default(), - selected: None, - save_eligibility: false, - }, - attach: Attach { - associated_player: None, - parent: None, - children: [None, None, None, None], - }, - }); - entity_id + let entity_id = commands + .spawn(PlayerBundle { + part: PartBundle { + part_type: PartType::Hearty, + transform: TransformBundle::from(transform), + flags: PartFlags { attached: false }, + }, + player: Player { + addr: *addr, + username: username.to_string(), + input: component::Input::default(), + selected: None, + save_eligibility: false, + }, + attach: Attach { + associated_player: None, + parent: None, + children: [None, None, None, None], + }, + }) .insert(Collider::cuboid( PART_HALF_SIZE / SCALE, PART_HALF_SIZE / SCALE, @@ -280,10 +305,29 @@ fn on_login( .insert(RigidBody::Dynamic); let id = entity_id.id().index(); - let mut planet_query = world.query::<(Entity, &PlanetType, &Transform)>(); + 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! + + load_savefile(&mut commands, transform, entity_id, entity_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)); + } + } else { + // nothing to do + } + // tell this player the planets let mut planets = Vec::new(); - for (entity, planet_type, transform) in planet_query.iter(&world) { + for (entity, planet_type, transform) in planet_query.iter() { let translation = transform.translation; planets.push(( entity.index(), @@ -305,15 +349,8 @@ fn on_login( 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.iter(&world) { + for (entity, player, _, _, _) in &player_query { players.push((entity.index(), player.username.clone())); } let packet = Packet::PlayerList { players }; @@ -336,18 +373,8 @@ fn on_login( 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.iter(&world) { + for (entity, part_type, transform, _, _, flags) in &part_query { parts.push(( entity.index(), Part { @@ -359,20 +386,7 @@ fn on_login( }, )); } - 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) - { + for (entity, part_type, transform, _, _, _, _, flags) in &attached_query { parts.push(( entity.index(), Part { @@ -407,282 +421,7 @@ fn on_login( }; let buf = serde_json::to_vec(&packet).unwrap(); event_queue.push(ServerEvent::Send(*addr, MessageType::Text, buf)); - 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)); - } - } else { - // 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; -} -// permissions: -// 0 - regular user (unauthenticated is 0) -// 10 - private alpha -// 20 - supervisor -// 30 - dev - -const REQUIRED_PERMISSION_LEVEL: i32 = 10; - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct UserToken { - pub id: i64, - pub username: String, - pub permission_level: i32, - pub expires: SystemTime, -} - -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::SendMessage { target, content } => { // find our player let mut player = None; @@ -1174,6 +913,169 @@ fn on_message( } } +fn load_savefile( + commands: &mut Commands, + transform: Transform, + player_id: Entity, + parent: Entity, + parent_attach: &mut Attach, + children: Vec>, + attached_query: &mut Query< + ( + Entity, + &PartType, + &mut Transform, + &mut Attach, + &Velocity, + Option<&CanAttach>, + Option<&LooseAttach>, + &mut PartFlags, + ), + (Without, Without), + >, + part_query: &mut Query< + ( + 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 module = commands.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 }, + }) + .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 child.part_type.into() == 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 = commands.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, + }); + attached_query.get_mut(parent).children[3] = Some(module); + //module.5.attached = true; + + ret = ret + | if *child.part_type.into() != PartType::LandingThruster { + load_savefile( + commands, + transform, + player_id, + module.id(), + child.children, + attached_query, + part_query, + ) + } else { + false + }; + } + } + return ret; +} + fn construct_save_data( attach: Attach, attached_query: &Query<