Added feature flag for terrain persistence

This commit is contained in:
Joshua Barretto 2021-08-12 10:48:00 +01:00
parent 738e59965f
commit c2498d81c7
8 changed files with 64 additions and 26 deletions

1
Cargo.lock generated
View File

@ -6075,6 +6075,7 @@ version = "0.10.0"
dependencies = [ dependencies = [
"atomicwrites", "atomicwrites",
"authc", "authc",
"bincode",
"chrono", "chrono",
"crossbeam-channel", "crossbeam-channel",
"futures-util", "futures-util",

View File

@ -16,9 +16,10 @@ This package includes the official server CLI.
[features] [features]
worldgen = ["server/worldgen"] worldgen = ["server/worldgen"]
persistent_world = ["server/persistent_world"]
# needed to stay compatible with voxygens format # needed to stay compatible with voxygens format
default-publish = ["default"] default-publish = ["default"]
default = ["worldgen"] default = ["worldgen", "persistent_world"]
tracy = ["common-frontend/tracy"] tracy = ["common-frontend/tracy"]
plugins = ["server/plugins"] plugins = ["server/plugins"]

View File

@ -8,8 +8,9 @@ edition = "2018"
worldgen = [] worldgen = []
simd = ["vek/platform_intrinsics"] simd = ["vek/platform_intrinsics"]
plugins = ["common-state/plugins"] plugins = ["common-state/plugins"]
persistent_world = []
default = ["worldgen", "plugins", "simd"] default = ["worldgen", "plugins", "simd", "persistent_world"]
[dependencies] [dependencies]
common = { package = "veloren-common", path = "../common" } common = { package = "veloren-common", path = "../common" }

View File

@ -529,6 +529,7 @@ fn handle_make_block(
let new_block = Block::new(bk, Rgb::new(r, g, b).map(|e| e.unwrap_or(255))); let new_block = Block::new(bk, Rgb::new(r, g, b).map(|e| e.unwrap_or(255)));
let pos = pos.0.map(|e| e.floor() as i32); let pos = pos.0.map(|e| e.floor() as i32);
server.state.set_block(pos, new_block); server.state.set_block(pos, new_block);
#[cfg(feature = "persistent_world")]
if let Some(terrain_persistence) = server if let Some(terrain_persistence) = server
.state .state
.ecs() .ecs()
@ -564,6 +565,7 @@ fn handle_make_sprite(
.unwrap_or_else(|| Block::air(SpriteKind::Empty)) .unwrap_or_else(|| Block::air(SpriteKind::Empty))
.with_sprite(sk); .with_sprite(sk);
server.state.set_block(pos, new_block); server.state.set_block(pos, new_block);
#[cfg(feature = "persistent_world")]
if let Some(terrain_persistence) = server if let Some(terrain_persistence) = server
.state .state
.ecs() .ecs()

View File

@ -31,6 +31,7 @@ pub mod rtsim;
pub mod settings; pub mod settings;
pub mod state_ext; pub mod state_ext;
pub mod sys; pub mod sys;
#[cfg(feature = "persistent_world")]
pub mod terrain_persistence; pub mod terrain_persistence;
#[cfg(not(feature = "worldgen"))] mod test_world; #[cfg(not(feature = "worldgen"))] mod test_world;
pub mod wiring; pub mod wiring;
@ -44,6 +45,8 @@ pub use crate::{
settings::{EditableSettings, Settings}, settings::{EditableSettings, Settings},
}; };
#[cfg(feature = "persistent_world")]
use crate::terrain_persistence::TerrainPersistence;
use crate::{ use crate::{
alias_validator::AliasValidator, alias_validator::AliasValidator,
chunk_generator::ChunkGenerator, chunk_generator::ChunkGenerator,
@ -56,7 +59,6 @@ use crate::{
rtsim::RtSim, rtsim::RtSim,
state_ext::StateExt, state_ext::StateExt,
sys::sentinel::{DeletedEntities, TrackedComps}, sys::sentinel::{DeletedEntities, TrackedComps},
terrain_persistence::TerrainPersistence,
}; };
#[cfg(not(feature = "worldgen"))] #[cfg(not(feature = "worldgen"))]
use common::grid::Grid; use common::grid::Grid;
@ -219,16 +221,24 @@ impl Server {
state.ecs_mut().insert(tick_metrics); state.ecs_mut().insert(tick_metrics);
state.ecs_mut().insert(physics_metrics); state.ecs_mut().insert(physics_metrics);
if settings.experimental_terrain_persistence { if settings.experimental_terrain_persistence {
#[cfg(feature = "persistent_world")]
{
warn!( warn!(
"Experimental terrain persistence support is enabled. This feature may break, be \ "Experimental terrain persistence support is enabled. This feature may break, \
disabled, or otherwise change under your feet at *any time*. Additionally, it is \ be disabled, or otherwise change under your feet at *any time*. \
expected to be replaced in the future *without* migration or warning. You have \ Additionally, it is expected to be replaced in the future *without* \
been warned." migration or warning. You have been warned."
); );
state state
.ecs_mut() .ecs_mut()
.insert(TerrainPersistence::new(data_dir.to_owned())); .insert(TerrainPersistence::new(data_dir.to_owned()));
} }
#[cfg(not(feature = "persistent_world"))]
error!(
"Experimental terrain persistence support was requested, but the server was not \
compiled with the feature. Terrain modifications will *not* be persisted."
);
}
state state
.ecs_mut() .ecs_mut()
.write_resource::<SlowJobPool>() .write_resource::<SlowJobPool>()
@ -874,6 +884,7 @@ impl Server {
self.state.cleanup(); self.state.cleanup();
// Maintain persisted terrain // Maintain persisted terrain
#[cfg(feature = "persistent_world")]
self.state self.state
.ecs() .ecs()
.try_fetch_mut::<TerrainPersistence>() .try_fetch_mut::<TerrainPersistence>()
@ -1253,8 +1264,11 @@ impl Server {
impl Drop for Server { impl Drop for Server {
fn drop(&mut self) { fn drop(&mut self) {
self.metrics_shutdown.notify_one(); self.metrics_shutdown.notify_one();
self.state self.state
.notify_players(ServerGeneral::Disconnect(DisconnectReason::Shutdown)); .notify_players(ServerGeneral::Disconnect(DisconnectReason::Shutdown));
#[cfg(feature = "persistent_world")]
self.state self.state
.ecs() .ecs()
.try_fetch_mut::<TerrainPersistence>() .try_fetch_mut::<TerrainPersistence>()

View File

@ -1,4 +1,6 @@
use crate::{client::Client, presence::Presence, Settings, TerrainPersistence}; #[cfg(feature = "persistent_world")]
use crate::TerrainPersistence;
use crate::{client::Client, presence::Presence, Settings};
use common::{ use common::{
comp::{ comp::{
Admin, CanBuild, ControlEvent, Controller, ForceUpdate, Health, Ori, Player, Pos, SkillSet, Admin, CanBuild, ControlEvent, Controller, ForceUpdate, Health, Ori, Player, Pos, SkillSet,
@ -16,6 +18,11 @@ use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage};
use tracing::{debug, trace, warn}; use tracing::{debug, trace, warn};
use vek::*; use vek::*;
#[cfg(feature = "persistent_world")]
pub type TerrainPersistenceData<'a> = Option<Write<'a, TerrainPersistence>>;
#[cfg(not(feature = "persistent_world"))]
pub type TerrainPersistenceData<'a> = ();
impl Sys { impl Sys {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn handle_client_in_game_msg( fn handle_client_in_game_msg(
@ -36,7 +43,7 @@ impl Sys {
settings: &Read<'_, Settings>, settings: &Read<'_, Settings>,
build_areas: &Read<'_, BuildAreas>, build_areas: &Read<'_, BuildAreas>,
player_physics_settings: &mut Write<'_, PlayerPhysicsSettings>, player_physics_settings: &mut Write<'_, PlayerPhysicsSettings>,
terrain_persistence: &mut Option<Write<'_, TerrainPersistence>>, _terrain_persistence: &mut TerrainPersistenceData<'_>,
maybe_player: &Option<&Player>, maybe_player: &Option<&Player>,
maybe_admin: &Option<&Admin>, maybe_admin: &Option<&Admin>,
msg: ClientGeneral, msg: ClientGeneral,
@ -200,9 +207,10 @@ impl Sys {
.and_then(|_| terrain.get(pos).ok()) .and_then(|_| terrain.get(pos).ok())
{ {
let new_block = old_block.into_vacant(); let new_block = old_block.into_vacant();
let was_placed = block_changes.try_set(pos, new_block).is_some(); let _was_set = block_changes.try_set(pos, new_block).is_some();
if was_placed { #[cfg(feature = "persistent_world")]
if let Some(terrain_persistence) = terrain_persistence.as_mut() if _was_set {
if let Some(terrain_persistence) = _terrain_persistence.as_mut()
{ {
terrain_persistence.set_block(pos, new_block); terrain_persistence.set_block(pos, new_block);
} }
@ -224,9 +232,10 @@ impl Sys {
.filter(|aabb| aabb.contains_point(pos)) .filter(|aabb| aabb.contains_point(pos))
.is_some() .is_some()
{ {
let was_placed = block_changes.try_set(pos, new_block).is_some(); let _was_set = block_changes.try_set(pos, new_block).is_some();
if was_placed { #[cfg(feature = "persistent_world")]
if let Some(terrain_persistence) = terrain_persistence.as_mut() if _was_set {
if let Some(terrain_persistence) = _terrain_persistence.as_mut()
{ {
terrain_persistence.set_block(pos, new_block); terrain_persistence.set_block(pos, new_block);
} }
@ -301,7 +310,7 @@ impl<'a> System<'a> for Sys {
Read<'a, Settings>, Read<'a, Settings>,
Read<'a, BuildAreas>, Read<'a, BuildAreas>,
Write<'a, PlayerPhysicsSettings>, Write<'a, PlayerPhysicsSettings>,
Option<Write<'a, TerrainPersistence>>, TerrainPersistenceData<'a>,
ReadStorage<'a, Player>, ReadStorage<'a, Player>,
ReadStorage<'a, Admin>, ReadStorage<'a, Admin>,
); );

View File

@ -1,3 +1,5 @@
#[cfg(feature = "persistent_world")]
use crate::TerrainPersistence;
use crate::{ use crate::{
chunk_generator::ChunkGenerator, chunk_generator::ChunkGenerator,
client::Client, client::Client,
@ -5,7 +7,7 @@ use crate::{
presence::{Presence, RepositionOnChunkLoad}, presence::{Presence, RepositionOnChunkLoad},
rtsim::RtSim, rtsim::RtSim,
settings::Settings, settings::Settings,
SpawnPoint, TerrainPersistence, Tick, SpawnPoint, Tick,
}; };
use common::{ use common::{
comp::{self, agent, bird_medium, Alignment, BehaviorCapability, ForceUpdate, Pos, Waypoint}, comp::{self, agent, bird_medium, Alignment, BehaviorCapability, ForceUpdate, Pos, Waypoint},
@ -24,6 +26,11 @@ use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteExpect, W
use std::sync::Arc; use std::sync::Arc;
use vek::*; use vek::*;
#[cfg(feature = "persistent_world")]
pub type TerrainPersistenceData<'a> = Option<Write<'a, TerrainPersistence>>;
#[cfg(not(feature = "persistent_world"))]
pub type TerrainPersistenceData<'a> = ();
pub(crate) struct LazyTerrainMessage { pub(crate) struct LazyTerrainMessage {
lazy_msg_lo: Option<crate::client::PreparedMsg>, lazy_msg_lo: Option<crate::client::PreparedMsg>,
lazy_msg_hi: Option<crate::client::PreparedMsg>, lazy_msg_hi: Option<crate::client::PreparedMsg>,
@ -99,7 +106,7 @@ impl<'a> System<'a> for Sys {
WriteExpect<'a, TerrainGrid>, WriteExpect<'a, TerrainGrid>,
Write<'a, TerrainChanges>, Write<'a, TerrainChanges>,
WriteExpect<'a, RtSim>, WriteExpect<'a, RtSim>,
Option<WriteExpect<'a, TerrainPersistence>>, TerrainPersistenceData<'a>,
WriteStorage<'a, Pos>, WriteStorage<'a, Pos>,
ReadStorage<'a, Presence>, ReadStorage<'a, Presence>,
ReadStorage<'a, Client>, ReadStorage<'a, Client>,
@ -126,7 +133,7 @@ impl<'a> System<'a> for Sys {
mut terrain, mut terrain,
mut terrain_changes, mut terrain_changes,
mut rtsim, mut rtsim,
mut terrain_persistence, mut _terrain_persistence,
mut positions, mut positions,
presences, presences,
clients, clients,
@ -143,6 +150,7 @@ impl<'a> System<'a> for Sys {
// Also, send the chunk data to anybody that is close by. // Also, send the chunk data to anybody that is close by.
let mut new_chunks = Vec::new(); let mut new_chunks = Vec::new();
'insert_terrain_chunks: while let Some((key, res)) = chunk_generator.recv_new_chunk() { 'insert_terrain_chunks: while let Some((key, res)) = chunk_generator.recv_new_chunk() {
#[allow(unused_mut)]
let (mut chunk, supplement) = match res { let (mut chunk, supplement) = match res {
Ok((chunk, supplement)) => (chunk, supplement), Ok((chunk, supplement)) => (chunk, supplement),
Err(Some(entity)) => { Err(Some(entity)) => {
@ -160,7 +168,8 @@ impl<'a> System<'a> for Sys {
}; };
// Apply changes from terrain persistence to this chunk // Apply changes from terrain persistence to this chunk
if let Some(terrain_persistence) = terrain_persistence.as_mut() { #[cfg(feature = "persistent_world")]
if let Some(terrain_persistence) = _terrain_persistence.as_mut() {
terrain_persistence.apply_changes(key, &mut chunk); terrain_persistence.apply_changes(key, &mut chunk);
} }
@ -417,7 +426,8 @@ impl<'a> System<'a> for Sys {
for key in chunks_to_remove { for key in chunks_to_remove {
// Register the unloading of this chunk from terrain persistence // Register the unloading of this chunk from terrain persistence
if let Some(terrain_persistence) = terrain_persistence.as_mut() { #[cfg(feature = "persistent_world")]
if let Some(terrain_persistence) = _terrain_persistence.as_mut() {
terrain_persistence.unload_chunk(key); terrain_persistence.unload_chunk(key);
} }

View File

@ -83,7 +83,7 @@ vek = {version = "=0.14.1", features = ["serde"]}
gilrs = {version = "0.8.0", features = ["serde-serialize"]} gilrs = {version = "0.8.0", features = ["serde-serialize"]}
# Singleplayer # Singleplayer
server = {package = "veloren-server", path = "../server", optional = true} server = { package = "veloren-server", path = "../server", optional = true, default-features = false, features = ["worldgen"] }
# Utility # Utility
backtrace = "0.3.40" backtrace = "0.3.40"