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 = [
"atomicwrites",
"authc",
"bincode",
"chrono",
"crossbeam-channel",
"futures-util",

View File

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

View File

@ -8,8 +8,9 @@ edition = "2018"
worldgen = []
simd = ["vek/platform_intrinsics"]
plugins = ["common-state/plugins"]
persistent_world = []
default = ["worldgen", "plugins", "simd"]
default = ["worldgen", "plugins", "simd", "persistent_world"]
[dependencies]
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 pos = pos.0.map(|e| e.floor() as i32);
server.state.set_block(pos, new_block);
#[cfg(feature = "persistent_world")]
if let Some(terrain_persistence) = server
.state
.ecs()
@ -564,6 +565,7 @@ fn handle_make_sprite(
.unwrap_or_else(|| Block::air(SpriteKind::Empty))
.with_sprite(sk);
server.state.set_block(pos, new_block);
#[cfg(feature = "persistent_world")]
if let Some(terrain_persistence) = server
.state
.ecs()

View File

@ -31,6 +31,7 @@ pub mod rtsim;
pub mod settings;
pub mod state_ext;
pub mod sys;
#[cfg(feature = "persistent_world")]
pub mod terrain_persistence;
#[cfg(not(feature = "worldgen"))] mod test_world;
pub mod wiring;
@ -44,6 +45,8 @@ pub use crate::{
settings::{EditableSettings, Settings},
};
#[cfg(feature = "persistent_world")]
use crate::terrain_persistence::TerrainPersistence;
use crate::{
alias_validator::AliasValidator,
chunk_generator::ChunkGenerator,
@ -56,7 +59,6 @@ use crate::{
rtsim::RtSim,
state_ext::StateExt,
sys::sentinel::{DeletedEntities, TrackedComps},
terrain_persistence::TerrainPersistence,
};
#[cfg(not(feature = "worldgen"))]
use common::grid::Grid;
@ -219,15 +221,23 @@ impl Server {
state.ecs_mut().insert(tick_metrics);
state.ecs_mut().insert(physics_metrics);
if settings.experimental_terrain_persistence {
warn!(
"Experimental terrain persistence support is enabled. This feature may break, be \
disabled, or otherwise change under your feet at *any time*. Additionally, it is \
expected to be replaced in the future *without* migration or warning. You have \
been warned."
#[cfg(feature = "persistent_world")]
{
warn!(
"Experimental terrain persistence support is enabled. This feature may break, \
be disabled, or otherwise change under your feet at *any time*. \
Additionally, it is expected to be replaced in the future *without* \
migration or warning. You have been warned."
);
state
.ecs_mut()
.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
.ecs_mut()
.insert(TerrainPersistence::new(data_dir.to_owned()));
}
state
.ecs_mut()
@ -874,6 +884,7 @@ impl Server {
self.state.cleanup();
// Maintain persisted terrain
#[cfg(feature = "persistent_world")]
self.state
.ecs()
.try_fetch_mut::<TerrainPersistence>()
@ -1253,8 +1264,11 @@ impl Server {
impl Drop for Server {
fn drop(&mut self) {
self.metrics_shutdown.notify_one();
self.state
.notify_players(ServerGeneral::Disconnect(DisconnectReason::Shutdown));
#[cfg(feature = "persistent_world")]
self.state
.ecs()
.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::{
comp::{
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 vek::*;
#[cfg(feature = "persistent_world")]
pub type TerrainPersistenceData<'a> = Option<Write<'a, TerrainPersistence>>;
#[cfg(not(feature = "persistent_world"))]
pub type TerrainPersistenceData<'a> = ();
impl Sys {
#[allow(clippy::too_many_arguments)]
fn handle_client_in_game_msg(
@ -36,7 +43,7 @@ impl Sys {
settings: &Read<'_, Settings>,
build_areas: &Read<'_, BuildAreas>,
player_physics_settings: &mut Write<'_, PlayerPhysicsSettings>,
terrain_persistence: &mut Option<Write<'_, TerrainPersistence>>,
_terrain_persistence: &mut TerrainPersistenceData<'_>,
maybe_player: &Option<&Player>,
maybe_admin: &Option<&Admin>,
msg: ClientGeneral,
@ -200,9 +207,10 @@ impl Sys {
.and_then(|_| terrain.get(pos).ok())
{
let new_block = old_block.into_vacant();
let was_placed = block_changes.try_set(pos, new_block).is_some();
if was_placed {
if let Some(terrain_persistence) = terrain_persistence.as_mut()
let _was_set = block_changes.try_set(pos, new_block).is_some();
#[cfg(feature = "persistent_world")]
if _was_set {
if let Some(terrain_persistence) = _terrain_persistence.as_mut()
{
terrain_persistence.set_block(pos, new_block);
}
@ -224,9 +232,10 @@ impl Sys {
.filter(|aabb| aabb.contains_point(pos))
.is_some()
{
let was_placed = block_changes.try_set(pos, new_block).is_some();
if was_placed {
if let Some(terrain_persistence) = terrain_persistence.as_mut()
let _was_set = block_changes.try_set(pos, new_block).is_some();
#[cfg(feature = "persistent_world")]
if _was_set {
if let Some(terrain_persistence) = _terrain_persistence.as_mut()
{
terrain_persistence.set_block(pos, new_block);
}
@ -301,7 +310,7 @@ impl<'a> System<'a> for Sys {
Read<'a, Settings>,
Read<'a, BuildAreas>,
Write<'a, PlayerPhysicsSettings>,
Option<Write<'a, TerrainPersistence>>,
TerrainPersistenceData<'a>,
ReadStorage<'a, Player>,
ReadStorage<'a, Admin>,
);

View File

@ -1,3 +1,5 @@
#[cfg(feature = "persistent_world")]
use crate::TerrainPersistence;
use crate::{
chunk_generator::ChunkGenerator,
client::Client,
@ -5,7 +7,7 @@ use crate::{
presence::{Presence, RepositionOnChunkLoad},
rtsim::RtSim,
settings::Settings,
SpawnPoint, TerrainPersistence, Tick,
SpawnPoint, Tick,
};
use common::{
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 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 {
lazy_msg_lo: Option<crate::client::PreparedMsg>,
lazy_msg_hi: Option<crate::client::PreparedMsg>,
@ -99,7 +106,7 @@ impl<'a> System<'a> for Sys {
WriteExpect<'a, TerrainGrid>,
Write<'a, TerrainChanges>,
WriteExpect<'a, RtSim>,
Option<WriteExpect<'a, TerrainPersistence>>,
TerrainPersistenceData<'a>,
WriteStorage<'a, Pos>,
ReadStorage<'a, Presence>,
ReadStorage<'a, Client>,
@ -126,7 +133,7 @@ impl<'a> System<'a> for Sys {
mut terrain,
mut terrain_changes,
mut rtsim,
mut terrain_persistence,
mut _terrain_persistence,
mut positions,
presences,
clients,
@ -143,6 +150,7 @@ impl<'a> System<'a> for Sys {
// Also, send the chunk data to anybody that is close by.
let mut new_chunks = Vec::new();
'insert_terrain_chunks: while let Some((key, res)) = chunk_generator.recv_new_chunk() {
#[allow(unused_mut)]
let (mut chunk, supplement) = match res {
Ok((chunk, supplement)) => (chunk, supplement),
Err(Some(entity)) => {
@ -160,7 +168,8 @@ impl<'a> System<'a> for Sys {
};
// 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);
}
@ -417,7 +426,8 @@ impl<'a> System<'a> for Sys {
for key in chunks_to_remove {
// 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);
}

View File

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