use crate::entity::EntityHandler;
use crate::module::{Module, AttachedModule, ModuleTemplate};
use crate::orbit::constants::{GAME_ORBITS_ENABLED, MARS_APHELION, MARS_ORBIT_TIME, MARS_PERIHELION, MOON_APOAPSIS, MOON_ORBIT_TIME, MOON_PERIAPSIS};
use crate::orbit::orbit::{calculate_point_on_orbit, calculate_world_position_of_orbit};
use crate::{
entity::{get_entity_id, Entity},
manager::{ClientHandlerMessage, ClientManager, PhysicsData},
planet::Planets,
SCALE,
};
use async_std::sync::RwLock;
use async_std::task::sleep;
use log::{warn, debug};
use nalgebra::{point, vector};
use protobuf::SpecialFields;
use rand::Rng;
use rapier2d_f64::prelude::{ColliderBuilder, MassProperties, PhysicsPipeline, RigidBodyBuilder, SharedShape};
use starkingdoms_protocol::{module::ModuleType, planet::PlanetType, player::Player};
use std::error::Error;
use std::{f64::consts::PI, sync::Arc, time::Duration};
pub const LATERAL_FORCE: f64 = 0.0002;
pub const MODULE_SPAWN: f64 = 3.0;
pub const MODULE_MAX: u32 = 10;
//noinspection ALL
pub async fn timer_main(
mgr: ClientManager,
physics_data_orig: Arc<RwLock<PhysicsData>>,
entities: Arc<RwLock<EntityHandler>>,
) -> Result<(), Box<dyn Error>> {
let mut pipeline = PhysicsPipeline::new();
let mut time = 0.0;
let mut module_timer = 0.0;
{
let mut data_handle = physics_data_orig.write().await;
let mut rigid_body_set = data_handle.rigid_body_set.clone();
let mut collider_set = data_handle.collider_set.clone();
let _ = Planets::create_planets(
&mut rigid_body_set,
&mut collider_set,
&mut entities.write().await.entities,
);
data_handle.rigid_body_set = rigid_body_set;
data_handle.collider_set = collider_set;
}
#[allow(clippy::significant_drop_tightening)]
// underdeveloped lint, TODO remove when its better
loop {
sleep(Duration::from_millis(5)).await;
time += 5.0 / 1000.0; // 5ms, time is in seconds
module_timer += 5.0 / 1000.0;
let mut physics_data = physics_data_orig.write().await;
// update orbits (but dont, actually, yet)
// DO NOT SIMPLIFY EXPRESSION
// IT MAY ALWAYS BE TRUE
// THATS FINE
if GAME_ORBITS_ENABLED {
let mut planets = entities.write().await;
let mut map = planets.entities.clone();
// update earth (nothing changes, yet)
let earth_id = planets.get_planet_id(PlanetType::Earth).ok_or("earth does not exist")?;
if let Entity::Planet(earth) = map
.get(&earth_id)
.ok_or("earth does not exist")? {
let new_earth_position = vector![earth.position.0, earth.position.1];
// update moon
let moon_id = planets.get_planet_id(PlanetType::Moon).ok_or("moon does not exist")?;
if let Entity::Planet(moon) = map
.get_mut(&moon_id)
.ok_or("moon does not exist")? {
let new_moon_position = calculate_world_position_of_orbit(
calculate_point_on_orbit(MOON_PERIAPSIS, MOON_APOAPSIS, time / MOON_ORBIT_TIME),
new_earth_position,
);
let new_moon_position = new_moon_position / SCALE;
let moon_body = physics_data
.rigid_body_set
.get_mut(moon.body_handle)
.ok_or("moon does not exist")?;
moon_body.set_next_kinematic_translation(new_moon_position);
moon.position = (
moon_body.translation()[0],
moon_body.translation()[1],
);
// update mars
let mars_id = planets.get_planet_id(PlanetType::Mars).ok_or("mars does not exist")?;
if let Entity::Planet(mars) = map
.get_mut(&mars_id)
.ok_or("mars does not exist")? {
let new_mars_position = calculate_world_position_of_orbit(
calculate_point_on_orbit(MARS_PERIHELION, MARS_APHELION, time / MARS_ORBIT_TIME),
new_moon_position,
);
let new_mars_position = new_mars_position/SCALE;
let mars_body = physics_data
.rigid_body_set
.get_mut(mars.body_handle)
.ok_or("mars does not exist")?;
mars_body.set_next_kinematic_translation(new_mars_position);
mars.position = (
mars_body.translation()[0],
mars_body.translation()[1],
);
}
}
}
planets.entities = map;
}
physics_data.tick(&mut pipeline);
let mut protocol_players = vec![];
{
if module_timer > MODULE_SPAWN && entities.read().await.get_module_count() < MODULE_MAX
{
module_timer = 0.;
let mut rigid_body_set = physics_data.rigid_body_set.clone();
let mut collider_set = physics_data.collider_set.clone();
let module_collider = ColliderBuilder::cuboid(18.75 / SCALE, 23.4375 / SCALE)
.translation(vector![0.0, 1.5625 / SCALE])
.mass_properties(MassProperties::new(point![0.0, 0.0], 0.000075, 0.005))
.build();
let angle: f64 = {
let mut rng = rand::thread_rng();
rng.gen::<f64>() * PI * 2.
};
let module_body = RigidBodyBuilder::dynamic()
.translation(vector![
angle.cos() * 2050. / SCALE,
angle.sin() * 2050.0 / SCALE
])
.build();
let module_handler = rigid_body_set.insert(module_body);
collider_set.insert_with_parent(
module_collider,
module_handler,
&mut rigid_body_set,
);
physics_data.rigid_body_set = rigid_body_set;
physics_data.collider_set = collider_set;
let module = Module {
handle: module_handler,
module_type: ModuleType::Cargo,
lifetime: 0.0,
flags: 0,
children: Vec::new(),
};
entities
.write()
.await
.entities
.insert(get_entity_id(), Entity::Module(module));
}
let mut entities = entities.write().await;
for module in &mut entities.get_all_attached() {
let module_handle = module.handle;
let module_body = physics_data
.rigid_body_set
.get_mut(module_handle)
.ok_or("module does not exist")?;
module_body.reset_forces(true);
module_body.reset_torques(true);
let grav_force = entities.gravity(
(module_body.translation().x, module_body.translation().y),
module_body.mass(),
);
module_body.apply_impulse(vector![grav_force.0, grav_force.1], true);
for child in module.children.clone() {
if let Some(child) = child {
if child.can_detach {
let joint = physics_data.impulse_joint_set
.get(child.connection).ok_or("module joint does not exist 190")?;
if joint.impulses.magnitude() > 0.00012 {
let module: Option<AttachedModule>;
if let Some(Entity::AttachedModule(p_module)) =
entities.entities.get_mut(&child.child)
{
module = Some(p_module.clone());
} else {
warn!("attempted to detach nonexistent module");
continue;
}
let player_id = module.as_ref().ok_or("cannot detach module that doesn't exist")?.player_id;
AttachedModule::detach(
&mut physics_data,
&mut entities,
player_id,
&module.ok_or("cannot detach module that doesn't exist")?,
);
}
}
}
}
if module.module_type == ModuleType::LandingThruster {
let player = entities.get_player_from_id(module.player_id).ok_or("attached module not affiliated with player")?;
let player_angle;
let player_translation;
{
let player_body = physics_data.rigid_body_set.get(player.handle).ok_or("player body does not exist")?;
player_angle = player_body.rotation().angle();
player_translation = *player_body.translation();
}
let module_body = physics_data.rigid_body_set.get_mut(module_handle).ok_or("module body does not exist")?;
let relative_angle = (module_body.rotation().angle() - player_angle).abs();
let relative_pos = module_body.translation() - player_translation;
let relative_pos = vector![
relative_pos.x.mul_add((-player_angle).cos(), -relative_pos.y * (-player_angle).sin()),
relative_pos.x.mul_add((-player_angle).sin(), relative_pos.y * (-player_angle).cos())
];
let rotation = module_body.rotation().angle();
if player.input.up {
if 3.*PI/4. < relative_angle && relative_angle < 5.*PI/4. {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
if player.input.down {
if (0. < relative_angle && relative_angle < PI/4.)||(7.*PI/4. < relative_angle && relative_angle < 2.*PI) {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
if player.input.left {
if 3.*PI/4. < relative_angle && relative_angle < 5.*PI/4. {
if relative_pos.x > 2.4 {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
if (0. < relative_angle && relative_angle < PI/4.)||(7.*PI/4. < relative_angle && relative_angle < 2.*PI) {
if relative_pos.x < -2.4 {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
if PI/4. < relative_angle && relative_angle < 3.*PI/4. {
if relative_pos.y < -2.4 {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
if 5.*PI/4. < relative_angle && relative_angle < 7.*PI/4. {
if relative_pos.y > 2.4 {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
if -2.4 < relative_pos.y && relative_pos.y < 2.4 {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
}
if player.input.right {
if 3.*PI/4. < relative_angle && relative_angle < 5.*PI/4. {
if relative_pos.x < -2.4 {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
if (0. < relative_angle && relative_angle < PI/4.)||(7.*PI/4. < relative_angle && relative_angle < 2.*PI) {
if relative_pos.x > 2.4 {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
if PI/4. < relative_angle && relative_angle < 3.*PI/4. {
if relative_pos.y > 2.4 {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
if -2.4 < relative_pos.y && relative_pos.y < 2.4 {
module_body.add_force_at_point(vector![
LATERAL_FORCE * 3. / SCALE * rotation.sin(),
-LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
if 5.*PI/4. < relative_angle && relative_angle < 7.*PI/4. {
if relative_pos.y < -2.4 {
module_body.add_force_at_point(vector![
-LATERAL_FORCE * 3. / SCALE * rotation.sin(),
LATERAL_FORCE * 3. / SCALE * rotation.cos()
], point![module_body.translation().x, module_body.translation().y], true);
}
}
}
}
}
}
{
let mut entities = entities.write().await;
for (player_id, player) in &entities.get_players() {
let player_handle = player.handle;
let player_body = physics_data
.rigid_body_set
.get_mut(player_handle)
.ok_or("player body does not exist")?;
player_body.reset_forces(true);
player_body.reset_torques(true);
let grav_force = entities.gravity(
(player_body.translation().x, player_body.translation().y),
player_body.mass(),
);
player_body.apply_impulse(vector![grav_force.0, grav_force.1], true);
let mut left_top_thruster: f64 = 0.0;
let mut right_top_thruster: f64 = 0.0;
let mut left_bottom_thruster: f64 = 0.0;
let mut right_bottom_thruster: f64 = 0.0;
if player.input.right {
left_top_thruster -= 1.0;
right_bottom_thruster += 1.0;
}
if player.input.left {
right_top_thruster -= 1.0;
left_bottom_thruster += 1.0;
}
if player.input.up {
left_bottom_thruster -= 1.0;
right_bottom_thruster -= 1.0;
}
if player.input.down {
left_top_thruster += 1.0;
right_top_thruster += 1.0;
}
left_top_thruster = LATERAL_FORCE * left_top_thruster.clamp(-1.0, 1.0);
right_top_thruster = LATERAL_FORCE * right_top_thruster.clamp(-1.0, 1.0);
left_bottom_thruster = LATERAL_FORCE * left_bottom_thruster.clamp(-1.0, 1.0);
right_bottom_thruster = LATERAL_FORCE * right_bottom_thruster.clamp(-1.0, 1.0);
let rotation = player_body.rotation().clone().angle();
let scale = SCALE;
let left_top_thruster = vector![
-left_top_thruster / scale * rotation.sin(),
left_top_thruster / scale * rotation.cos()
];
let right_top_thruster = vector![
-right_top_thruster / scale * rotation.sin(),
right_top_thruster / scale * rotation.cos()
];
let left_bottom_thruster = vector![
-left_bottom_thruster / scale * rotation.sin(),
left_bottom_thruster / scale * rotation.cos()
];
let right_bottom_thruster = vector![
-right_bottom_thruster / scale * rotation.sin(),
right_bottom_thruster / scale * rotation.cos()
];
let top_left_point = point![
(-25. / scale).mul_add(rotation.cos(), 25. / scale * rotation.sin()),
(-25. / scale).mul_add(rotation.sin(), -25. / scale * rotation.cos())
] + player_body.translation();
let top_right_point = point![
(25. / scale).mul_add(rotation.cos(), 25. / scale * rotation.sin()),
(25. / scale).mul_add(rotation.sin(), -25. / scale * rotation.cos())
] + player_body.translation();
let bottom_left_point = point![
(-25. / scale).mul_add(rotation.cos(), -25. / scale * rotation.sin()),
(-25. / scale).mul_add(rotation.sin(), 25. / scale * rotation.cos())
] + player_body.translation();
let bottom_right_point = point![
(25. / scale).mul_add(rotation.cos(), -25. / scale * rotation.sin()),
(25. / scale).mul_add(rotation.sin(), 25. / scale * rotation.cos())
] + player_body.translation();
player_body.add_force_at_point(left_top_thruster, top_left_point, true);
player_body.add_force_at_point(right_top_thruster, top_right_point, true);
player_body.add_force_at_point(left_bottom_thruster, bottom_left_point, true);
player_body.add_force_at_point(right_bottom_thruster, bottom_right_point, true);
let translation = player_body.translation();
let username;
{
let usernames = mgr.usernames.read().await;
username = usernames
.get(player_id)
.ok_or("username does not exist")?
.clone();
}
protocol_players.push(Player {
rotation,
x: (translation.x * SCALE),
y: (translation.y * SCALE),
username,
special_fields: SpecialFields::default(),
});
for child in player.children.clone() {
if let Some(child) = child {
let joint = match physics_data.impulse_joint_set
.get(child.connection) {
Some(c) => c,
None => { warn!("module joint doesn't exist"); continue; }
};
// displays impulse on joint * 10000 so its visible, use to tune breaking
// force
//debug!("impulse: {}", joint.impulses.magnitude() * 10000.);
if joint.impulses.magnitude() > 0.00012 {
let module: Option<AttachedModule>;
if let Some(Entity::AttachedModule(p_module)) =
entities.entities.get_mut(&child.child)
{
module = Some(p_module.clone());
} else {
warn!("attempted to detach nonexistent module");
continue;
}
let player_id = module.as_ref().ok_or("cannot detach module that doesn't exist")?.player_id;
AttachedModule::detach(
&mut physics_data,
&mut entities,
player_id,
&module.ok_or("cannot detach module that doesn't exist")?,
);
}
}
}
}
}
{
let mut entities = entities.write().await;
for planet in &entities.get_planets() {
let body = physics_data.rigid_body_set.get(planet.body_handle).ok_or("planet body not found")?;
let collider = body.colliders()[1];
let narrow = physics_data.narrow_phase.clone();
for (collider1, collider2, intersecting) in narrow.intersections_with(collider) {
if intersecting {
if collider1 == collider {
let collider_handle = match physics_data.collider_set.get_mut(collider2).ok_or("body doesn't exist collider2") {
Ok(c) => c,
Err(s) => { warn!("{}", s); continue; }
};
let body_handle = collider_handle.parent().ok_or("collider not attached to body")?;
let entity = entities.get_entity_from_handle(body_handle).ok_or("entity body doesn't exist")?;
match entity {
Entity::Player(player) => {
let tree = player.search_modules(&entities);
for module in tree {
if module.module_type == ModuleType::Cargo {
let module_id = entities.get_id_from_attached(&module)
.ok_or("module doesn't exist")?;
let module_handle =physics_data.rigid_body_set.get(module.handle)
.ok_or("attached module body does not exist")?.colliders()[0];
let module_collider = physics_data.collider_set.get_mut(module_handle)
.ok_or("attached module collider does not exist")?;
if let Entity::AttachedModule(attached) = entities.entities.get_mut(&module_id)
.ok_or("module doesn't exist")? {
match planet.planet_type {
PlanetType::Mars => {
attached.module_type = ModuleType::Hub;
module_collider.set_shape(SharedShape::cuboid(25./SCALE, 25./SCALE));
module_collider.set_translation_wrt_parent(vector![0., 0.]);
}
PlanetType::Moon => {
attached.module_type = ModuleType::LandingThruster;
module_collider.set_shape(SharedShape::cuboid(25./SCALE, 18.75/SCALE));
module_collider.set_translation_wrt_parent(vector![0., 6.25/SCALE]);
AttachedModule::attach_new(&mut physics_data, &mut entities,
module_id, module.player_id,
&ModuleTemplate {
mass_properties: MassProperties::new(point![0.0, 0.0], 0.000075, 0.005),
module_type: ModuleType::LandingThrusterSuspension,
}, 2);
}
_ => {}
};
}
}
}
}
Entity::AttachedModule(module) => {
let tree = entities.get_player_from_id(module.player_id).ok_or("player not found on attached")?
.search_modules(&entities);
for module in tree {
if module.module_type == ModuleType::Cargo {
let module_id = entities.get_id_from_attached(&module)
.ok_or("attached module doesn't exist")?;
let module_handle =physics_data.rigid_body_set.get(module.handle)
.ok_or("attached module body does not exist")?.colliders()[0];
let module_collider = physics_data.collider_set.get_mut(module_handle)
.ok_or("attached module collider does not exist")?;
if let Entity::AttachedModule(attached) = entities.entities.get_mut(&module_id)
.ok_or("module doesn't exist")? {
match planet.planet_type {
PlanetType::Mars => {
attached.module_type = ModuleType::Hub;
module_collider.set_shape(SharedShape::cuboid(25./SCALE, 25./SCALE));
module_collider.set_translation_wrt_parent(vector![0., 0.]);
}
PlanetType::Moon => {
attached.module_type = ModuleType::LandingThruster;
module_collider.set_shape(SharedShape::cuboid(25./SCALE, 18.75/SCALE));
module_collider.set_translation_wrt_parent(vector![0., 6.25/SCALE]);
AttachedModule::attach_new(&mut physics_data, &mut entities,
module_id, module.player_id,
&ModuleTemplate {
mass_properties: MassProperties::new(point![0.0, 0.0], 0.000075, 0.005),
module_type: ModuleType::LandingThrusterSuspension,
}, 2);
}
_ => {}
};
}
}
}
}
_ => {}
}
}
}
}
}
for module in &mut entities.get_modules() {
let module_handle = module.handle;
let module_body = physics_data
.rigid_body_set
.get_mut(module_handle)
.ok_or("module does not exist")?;
module_body.reset_forces(true);
module_body.reset_torques(true);
let grav_force = entities.gravity(
(module_body.translation().x, module_body.translation().y),
module_body.mass(),
);
module_body.apply_impulse(vector![grav_force.0, grav_force.1], true);
let id = entities
.get_from_module(module)
.ok_or("module entity does not exist")?;
if let Entity::Module(p_module) = entities
.entities
.get_mut(&id)
.ok_or("module does not exist")?
{
p_module.lifetime += 5. / 1000.;
}
if module.lifetime > 80. {
let mut rigid_body_set = physics_data.rigid_body_set.clone();
let mut island_manager = physics_data.island_manager.clone();
let mut collider_set = physics_data.collider_set.clone();
let mut impulse_joint_set = physics_data.impulse_joint_set.clone();
let mut multibody_joint_set = physics_data.multibody_joint_set.clone();
rigid_body_set.remove(
module.handle,
&mut island_manager,
&mut collider_set,
&mut impulse_joint_set,
&mut multibody_joint_set,
true,
);
physics_data.rigid_body_set = rigid_body_set;
physics_data.collider_set = collider_set;
physics_data.island_manager = island_manager;
physics_data.impulse_joint_set = impulse_joint_set;
physics_data.multibody_joint_set = multibody_joint_set;
entities.entities.remove(&id);
}
}
}
let mut to_remove = vec![];
let mut mgr_w = mgr.handlers.write().await;
let mgr_r = mgr_w.clone();
for (addr, client_thread) in &mgr_r {
match client_thread.tx.send(ClientHandlerMessage::Tick).await {
Ok(_) => {
match client_thread
.tx
.send(ClientHandlerMessage::PlayersUpdate {
players: protocol_players.clone(),
})
.await
{
Ok(_) => (),
Err(e) => {
warn!("unable to send position packet: {}", e);
}
};
let modules = entities.read().await.get_modules_id();
let entities = entities.read().await;
let this_player = entities.get_player_id(*addr);
let mut attached_modules: Vec<starkingdoms_protocol::module::AttachedModule> =
Vec::new();
let unattached_modules = entities.get_all_attached();
let mut unattached_modules: Vec<starkingdoms_protocol::module::Module> =
unattached_modules
.iter()
.filter(|m| match this_player {
Some(id) => {
if m.player_id == id {
#[allow(clippy::expect_used)]
{
attached_modules.push(
m.to_protocol(
&entities,
&physics_data.rigid_body_set,
)
.expect("module does not exist"),
);
}
false
} else {
true
}
}
None => true,
})
.map(|m| {
let id;
let module;
#[allow(clippy::expect_used)]
{
(id, module) =
m.to_module_id(&entities).expect("unable to get module id");
}
//info!("{:?}", module);
let body;
#[allow(clippy::expect_used)]
{
body = physics_data
.rigid_body_set
.get(module.handle)
.expect("module body does not exist");
}
let children = module.children.iter().map(|c| {
starkingdoms_protocol::module::Attachment {
id: c.child,
slot: 0,
special_fields: SpecialFields::default(),
}
}).collect();
starkingdoms_protocol::module::Module {
module_type: module.module_type.into(),
rotation: body.rotation().angle(),
x: body.translation().x * SCALE,
y: body.translation().y * SCALE,
id,
flags: module.flags,
children,
special_fields: SpecialFields::default(),
}
})
.collect();
let mut protocol_modules: Vec<starkingdoms_protocol::module::Module> = modules
.iter()
.map(|(id, module)| {
let body;
#[allow(clippy::expect_used)]
{
body = physics_data
.rigid_body_set
.get(module.handle)
.expect("module body does not exist");
}
let children = module.children.iter().map(|c| {
starkingdoms_protocol::module::Attachment {
id: c.child,
slot: 0,
special_fields: SpecialFields::default(),
}
}).collect();
starkingdoms_protocol::module::Module {
module_type: module.module_type.into(),
rotation: body.rotation().angle(),
x: body.translation().x * SCALE,
y: body.translation().y * SCALE,
id: *id,
flags: module.flags,
children,
special_fields: SpecialFields::default(),
}
})
.collect();
protocol_modules.append(&mut unattached_modules);
match client_thread
.tx
.send(ClientHandlerMessage::ModulesUpdate {
modules: protocol_modules.clone(),
})
.await
{
Ok(_) => (),
Err(e) => {
warn!("unable to send module position packet: {}", e);
}
};
match client_thread
.tx
.send(ClientHandlerMessage::ModuleTreeUpdate {
modules: attached_modules,
})
.await
{
Ok(_) => (),
Err(e) => {
warn!("unable to send module tree update packet: {}", e);
}
}
let planet_data = entities.to_protocol();
match client_thread.tx.send(planet_data).await {
Ok(_) => (),
Err(e) => {
warn!("unable to send earth packet: {}", e);
}
};
}
Err(e) => {
warn!("unable to update a client thread: {}", e);
to_remove.push(addr);
}
}
}
for pending_removal in to_remove {
mgr_w.remove(pending_removal);
}
}
}