@@ 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<PlanetType>, Without<Player>, Without<Attach>),
+ >,
+ mut attached_query: Query<
+ (
+ Entity,
+ &PartType,
+ &mut Transform,
+ &mut Attach,
+ &Velocity,
+ Option<&CanAttach>,
+ Option<&LooseAttach>,
+ &mut PartFlags,
+ ),
+ (Without<PlanetType>, Without<Player>),
+ >,
+ mut player_query: Query<
+ (Entity, &mut Player, &Transform, &Velocity, &mut Attach),
+ Without<PlanetType>,
+ >,
mut packet_recv: Local<ManualEventReader<ServerEvent>>,
- mut packet_event_send: Local<Events<ServerEvent>>,
+ mut packet_event_send: ResMut<Events<ServerEvent>>,
+ app_keys: Res<AppKeys>,
) {
- let app_keys = world.resource::<AppKeys>().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::<f32>() * 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<PlanetType>>();
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<PlanetType>, Without<Player>, Without<Attach>)>(
- );
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<PlanetType>, Without<Player>)>(
- );
- 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::<Attach>().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<Option<SaveModule>>,
- attached_query: &mut QueryState<
- (
- Entity,
- &PartType,
- &mut Transform,
- &mut Attach,
- &Velocity,
- Option<&CanAttach>,
- Option<&LooseAttach>,
- &mut PartFlags,
- ),
- (Without<PlanetType>, Without<Player>),
- >,
- part_query: &mut QueryState<
- (
- Entity,
- &PartType,
- &mut Transform,
- &mut Velocity,
- Option<&LooseAttach>,
- &mut PartFlags,
- ),
- (Without<PlanetType>, Without<Player>, Without<Attach>),
- >,
-) -> 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::<Attach>().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<PlanetType>, Without<Player>, Without<Attach>),
- >,
- mut attached_query: Query<
- (
- Entity,
- &PartType,
- &mut Transform,
- &mut Attach,
- &Velocity,
- Option<&CanAttach>,
- Option<&LooseAttach>,
- &mut PartFlags,
- ),
- (Without<PlanetType>, Without<Player>),
- >,
- mut player_query: Query<
- (Entity, &mut Player, &Transform, &Velocity, &mut Attach),
- Without<PlanetType>,
- >,
- mut packet_recv: Local<ManualEventReader<ServerEvent>>,
- mut packet_event_send: ResMut<Events<ServerEvent>>,
- app_keys: Res<AppKeys>,
-) {
- 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<Option<SaveModule>>,
+ attached_query: &mut Query<
+ (
+ Entity,
+ &PartType,
+ &mut Transform,
+ &mut Attach,
+ &Velocity,
+ Option<&CanAttach>,
+ Option<&LooseAttach>,
+ &mut PartFlags,
+ ),
+ (Without<PlanetType>, Without<Player>),
+ >,
+ part_query: &mut Query<
+ (
+ Entity,
+ &PartType,
+ &mut Transform,
+ &mut Velocity,
+ Option<&LooseAttach>,
+ &mut PartFlags,
+ ),
+ (Without<PlanetType>, Without<Player>, Without<Attach>),
+ >,
+) -> 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<