@@ 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<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>,
- >,
+fn on_login(
+ world: &mut World,
mut packet_recv: Local<ManualEventReader<ServerEvent>>,
- mut packet_event_send: ResMut<Events<ServerEvent>>,
- app_keys: Res<AppKeys>,
+ mut packet_event_send: Local<Events<ServerEvent>>,
) {
+ 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 {
@@ 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::<f32>() * 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<PlanetType>>();
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<PlanetType>, Without<Player>, Without<Attach>)>();
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<PlanetType>, Without<Player>)>();
+ 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::<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));
}
- 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<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;
+}
+
+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::PlayerInput {
up,
down,
@@ 911,6 1066,7 @@ fn on_message(
}
}
+
fn construct_save_data(
attach: Attach,
attached_query: &Query<