forked from feather-rs/feather
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshutdown.rs
More file actions
89 lines (71 loc) · 2.42 KB
/
shutdown.rs
File metadata and controls
89 lines (71 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//! Shutdown behavior.
use anyhow::Context;
use feather_core::network::packets::DisconnectPlay;
use feather_core::text::{TextRoot, TextValue};
use feather_server_chunk::chunk_worker::Request;
use feather_server_chunk::{save_chunk_at, ChunkWorkerHandle};
use feather_server_lighting::LightingWorkerHandle;
use feather_server_types::{tasks, Game, Network, Player};
use fecs::{IntoQuery, Read, World};
use tokio::fs::File;
use tokio::io::AsyncWriteExt;
pub fn init(tx: crossbeam::Sender<()>) {
ctrlc::set_handler(move || tx.try_send(()).unwrap()).unwrap();
}
pub fn disconnect_players(world: &World) -> anyhow::Result<()> {
<Read<Network>>::query().for_each(world.inner(), |network| {
let packet = DisconnectPlay {
reason: TextRoot::from(TextValue::translate(
"multiplayer.disconnect.server_shutdown",
))
.into(),
};
network.send(packet);
});
Ok(())
}
pub fn save_chunks(
game: &Game,
cworker_handle: &ChunkWorkerHandle,
world: &World,
) -> anyhow::Result<()> {
for chunk in game.chunk_map.iter_chunks() {
let pos = chunk.read().position();
save_chunk_at(game, world, pos, cworker_handle);
}
// Wait for chunk worker to shut down
let _ = cworker_handle.sender.send(Request::ShutDown);
while cworker_handle.receiver.recv().is_ok() {}
Ok(())
}
pub async fn save_level(game: &mut Game) -> anyhow::Result<()> {
// Sync world time + level time
let time = game.time.world_age() as i64;
game.level.time = time;
let level_path = format!("{}/{}", game.config.world.name, "level.dat");
let mut file = File::create(&level_path).await?;
game.level
.save_to_file(&mut file)
.await
.context("failed to save level file")?;
file.flush().await?;
Ok(())
}
pub fn save_player_data(game: &Game, world: &World) -> anyhow::Result<()> {
<Read<Player>>::query().for_each_entities(&world.inner(), |(player, _)| {
feather_server_chunk::save_player_data(game, world, player);
});
Ok(())
}
pub async fn wait_for_task_completion() -> anyhow::Result<()> {
tasks().wait().await;
Ok(())
}
pub fn shut_down_workers(_game: &Game, light_handle: &LightingWorkerHandle) -> anyhow::Result<()> {
let _ = light_handle
.tx
.send(feather_server_lighting::Request::ShutDown);
// wait for disconnect
let _ = light_handle.shutdown_rx.recv();
Ok(())
}