mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'xvar/rework-char-deletes' into 'master'
Character deletes are now processed by CharacterUpdater and clear any pending... See merge request veloren/veloren!2128
This commit is contained in:
commit
b6cd1f836e
@ -610,11 +610,20 @@ impl Server {
|
|||||||
// 7 Persistence updates
|
// 7 Persistence updates
|
||||||
let before_persistence_updates = Instant::now();
|
let before_persistence_updates = Instant::now();
|
||||||
|
|
||||||
// Get character-related database responses and notify the requesting client
|
let character_loader = self
|
||||||
self.state
|
.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.read_resource::<persistence::character_loader::CharacterLoader>()
|
.read_resource::<persistence::character_loader::CharacterLoader>();
|
||||||
|
|
||||||
|
let character_updater = self
|
||||||
|
.state
|
||||||
|
.ecs()
|
||||||
|
.read_resource::<persistence::character_updater::CharacterUpdater>();
|
||||||
|
|
||||||
|
// Get character-related database responses and notify the requesting client
|
||||||
|
character_loader
|
||||||
.messages()
|
.messages()
|
||||||
|
.chain(character_updater.messages())
|
||||||
.for_each(|query_result| match query_result.result {
|
.for_each(|query_result| match query_result.result {
|
||||||
CharacterLoaderResponseKind::CharacterList(result) => match result {
|
CharacterLoaderResponseKind::CharacterList(result) => match result {
|
||||||
Ok(character_list_data) => self.notify_client(
|
Ok(character_list_data) => self.notify_client(
|
||||||
@ -671,6 +680,9 @@ impl Server {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
drop(character_loader);
|
||||||
|
drop(character_updater);
|
||||||
|
|
||||||
{
|
{
|
||||||
// Check for new chunks; cancel and regenerate all chunks if the asset has been
|
// Check for new chunks; cancel and regenerate all chunks if the asset has been
|
||||||
// reloaded. Note that all of these assignments are no-ops, so the
|
// reloaded. Note that all of these assignments are no-ops, so the
|
||||||
|
@ -9,7 +9,7 @@ extern crate rusqlite;
|
|||||||
use super::{error::PersistenceError, models::*};
|
use super::{error::PersistenceError, models::*};
|
||||||
use crate::{
|
use crate::{
|
||||||
comp,
|
comp,
|
||||||
comp::{item::MaterialStatManifest, Inventory},
|
comp::Inventory,
|
||||||
persistence::{
|
persistence::{
|
||||||
character::conversions::{
|
character::conversions::{
|
||||||
convert_body_from_database, convert_body_to_database_json,
|
convert_body_from_database, convert_body_to_database_json,
|
||||||
@ -101,7 +101,6 @@ pub fn load_character_data(
|
|||||||
requesting_player_uuid: String,
|
requesting_player_uuid: String,
|
||||||
char_id: CharacterId,
|
char_id: CharacterId,
|
||||||
connection: &mut Transaction,
|
connection: &mut Transaction,
|
||||||
msm: &MaterialStatManifest,
|
|
||||||
) -> CharacterDataResult {
|
) -> CharacterDataResult {
|
||||||
let character_containers = get_pseudo_containers(connection, char_id)?;
|
let character_containers = get_pseudo_containers(connection, char_id)?;
|
||||||
let inventory_items = load_items_bfs(connection, character_containers.inventory_container_id)?;
|
let inventory_items = load_items_bfs(connection, character_containers.inventory_container_id)?;
|
||||||
@ -205,7 +204,6 @@ pub fn load_character_data(
|
|||||||
&inventory_items,
|
&inventory_items,
|
||||||
character_containers.loadout_container_id,
|
character_containers.loadout_container_id,
|
||||||
&loadout_items,
|
&loadout_items,
|
||||||
msm,
|
|
||||||
)?,
|
)?,
|
||||||
char_waypoint,
|
char_waypoint,
|
||||||
))
|
))
|
||||||
@ -221,7 +219,6 @@ pub fn load_character_data(
|
|||||||
pub fn load_character_list(
|
pub fn load_character_list(
|
||||||
player_uuid_: &str,
|
player_uuid_: &str,
|
||||||
connection: &mut Transaction,
|
connection: &mut Transaction,
|
||||||
msm: &MaterialStatManifest,
|
|
||||||
) -> CharacterListResult {
|
) -> CharacterListResult {
|
||||||
let characters;
|
let characters;
|
||||||
{
|
{
|
||||||
@ -282,7 +279,7 @@ pub fn load_character_list(
|
|||||||
let loadout_items = load_items_bfs(connection, loadout_container_id)?;
|
let loadout_items = load_items_bfs(connection, loadout_container_id)?;
|
||||||
|
|
||||||
let loadout =
|
let loadout =
|
||||||
convert_loadout_from_database_items(loadout_container_id, &loadout_items, msm)?;
|
convert_loadout_from_database_items(loadout_container_id, &loadout_items)?;
|
||||||
|
|
||||||
Ok(CharacterItem {
|
Ok(CharacterItem {
|
||||||
character: char,
|
character: char,
|
||||||
@ -298,7 +295,6 @@ pub fn create_character(
|
|||||||
character_alias: &str,
|
character_alias: &str,
|
||||||
persisted_components: PersistedComponents,
|
persisted_components: PersistedComponents,
|
||||||
connection: &mut Transaction,
|
connection: &mut Transaction,
|
||||||
msm: &MaterialStatManifest,
|
|
||||||
) -> CharacterCreationResult {
|
) -> CharacterCreationResult {
|
||||||
check_character_limit(uuid, connection)?;
|
check_character_limit(uuid, connection)?;
|
||||||
|
|
||||||
@ -445,7 +441,7 @@ pub fn create_character(
|
|||||||
}
|
}
|
||||||
drop(stmt);
|
drop(stmt);
|
||||||
|
|
||||||
load_character_list(uuid, connection, msm).map(|list| (character_id, list))
|
load_character_list(uuid, connection).map(|list| (character_id, list))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Delete a character. Returns the updated character list.
|
/// Delete a character. Returns the updated character list.
|
||||||
@ -453,7 +449,6 @@ pub fn delete_character(
|
|||||||
requesting_player_uuid: &str,
|
requesting_player_uuid: &str,
|
||||||
char_id: CharacterId,
|
char_id: CharacterId,
|
||||||
connection: &mut Transaction,
|
connection: &mut Transaction,
|
||||||
msm: &MaterialStatManifest,
|
|
||||||
) -> CharacterListResult {
|
) -> CharacterListResult {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let mut stmt = connection.prepare_cached("
|
let mut stmt = connection.prepare_cached("
|
||||||
@ -549,7 +544,7 @@ pub fn delete_character(
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
load_character_list(requesting_player_uuid, connection, msm)
|
load_character_list(requesting_player_uuid, connection)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Before creating a character, we ensure that the limit on the number of
|
/// Before creating a character, we ensure that the limit on the number of
|
||||||
|
@ -22,6 +22,7 @@ use common::{
|
|||||||
};
|
};
|
||||||
use core::{convert::TryFrom, num::NonZeroU64};
|
use core::{convert::TryFrom, num::NonZeroU64};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use std::{collections::VecDeque, sync::Arc};
|
use std::{collections::VecDeque, sync::Arc};
|
||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
|
|
||||||
@ -31,6 +32,13 @@ pub struct ItemModelPair {
|
|||||||
pub model: Item,
|
pub model: Item,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Decoupled from the ECS resource because the plumbing is getting complicated;
|
||||||
|
// shouldn't matter unless someone's hot-reloading material stats on the live
|
||||||
|
// server
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref MATERIAL_STATS_MANIFEST: MaterialStatManifest = MaterialStatManifest::default();
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a vector that contains all item rows to upsert; parent is
|
/// Returns a vector that contains all item rows to upsert; parent is
|
||||||
/// responsible for deleting items from the same owner that aren't affirmatively
|
/// responsible for deleting items from the same owner that aren't affirmatively
|
||||||
/// kept by this.
|
/// kept by this.
|
||||||
@ -230,7 +238,6 @@ pub fn convert_inventory_from_database_items(
|
|||||||
inventory_items: &[Item],
|
inventory_items: &[Item],
|
||||||
loadout_container_id: i64,
|
loadout_container_id: i64,
|
||||||
loadout_items: &[Item],
|
loadout_items: &[Item],
|
||||||
msm: &MaterialStatManifest,
|
|
||||||
) -> Result<Inventory, PersistenceError> {
|
) -> Result<Inventory, PersistenceError> {
|
||||||
// Loadout items must be loaded before inventory items since loadout items
|
// Loadout items must be loaded before inventory items since loadout items
|
||||||
// provide inventory slots. Since items stored inside loadout items actually
|
// provide inventory slots. Since items stored inside loadout items actually
|
||||||
@ -238,7 +245,7 @@ pub fn convert_inventory_from_database_items(
|
|||||||
// on populating the loadout items first, and then inserting the items into the
|
// on populating the loadout items first, and then inserting the items into the
|
||||||
// inventory at the correct position.
|
// inventory at the correct position.
|
||||||
//
|
//
|
||||||
let loadout = convert_loadout_from_database_items(loadout_container_id, loadout_items, msm)?;
|
let loadout = convert_loadout_from_database_items(loadout_container_id, loadout_items)?;
|
||||||
let mut inventory = Inventory::new_with_loadout(loadout);
|
let mut inventory = Inventory::new_with_loadout(loadout);
|
||||||
let mut item_indices = HashMap::new();
|
let mut item_indices = HashMap::new();
|
||||||
|
|
||||||
@ -310,7 +317,7 @@ pub fn convert_inventory_from_database_items(
|
|||||||
}
|
}
|
||||||
} else if let Some(&j) = item_indices.get(&db_item.parent_container_item_id) {
|
} else if let Some(&j) = item_indices.get(&db_item.parent_container_item_id) {
|
||||||
if let Some(Some(parent)) = inventory.slot_mut(slot(&inventory_items[j].position)?) {
|
if let Some(Some(parent)) = inventory.slot_mut(slot(&inventory_items[j].position)?) {
|
||||||
parent.add_component(item, msm);
|
parent.add_component(item, &MATERIAL_STATS_MANIFEST);
|
||||||
} else {
|
} else {
|
||||||
return Err(PersistenceError::ConversionError(format!(
|
return Err(PersistenceError::ConversionError(format!(
|
||||||
"Parent slot {} for component {} was empty even though it occurred earlier in \
|
"Parent slot {} for component {} was empty even though it occurred earlier in \
|
||||||
@ -332,7 +339,6 @@ pub fn convert_inventory_from_database_items(
|
|||||||
pub fn convert_loadout_from_database_items(
|
pub fn convert_loadout_from_database_items(
|
||||||
loadout_container_id: i64,
|
loadout_container_id: i64,
|
||||||
database_items: &[Item],
|
database_items: &[Item],
|
||||||
msm: &MaterialStatManifest,
|
|
||||||
) -> Result<Loadout, PersistenceError> {
|
) -> Result<Loadout, PersistenceError> {
|
||||||
let loadout_builder = LoadoutBuilder::new();
|
let loadout_builder = LoadoutBuilder::new();
|
||||||
let mut loadout = loadout_builder.build();
|
let mut loadout = loadout_builder.build();
|
||||||
@ -367,7 +373,7 @@ pub fn convert_loadout_from_database_items(
|
|||||||
} else if let Some(&j) = item_indices.get(&db_item.parent_container_item_id) {
|
} else if let Some(&j) = item_indices.get(&db_item.parent_container_item_id) {
|
||||||
loadout
|
loadout
|
||||||
.update_item_at_slot_using_persistence_key(&database_items[j].position, |parent| {
|
.update_item_at_slot_using_persistence_key(&database_items[j].position, |parent| {
|
||||||
parent.add_component(item, msm);
|
parent.add_component(item, &MATERIAL_STATS_MANIFEST);
|
||||||
})
|
})
|
||||||
.map_err(convert_error)?;
|
.map_err(convert_error)?;
|
||||||
} else {
|
} else {
|
||||||
|
@ -3,12 +3,8 @@ use crate::persistence::{
|
|||||||
error::PersistenceError,
|
error::PersistenceError,
|
||||||
establish_connection, DatabaseSettings, PersistedComponents,
|
establish_connection, DatabaseSettings, PersistedComponents,
|
||||||
};
|
};
|
||||||
use common::{
|
use common::character::{CharacterId, CharacterItem};
|
||||||
character::{CharacterId, CharacterItem},
|
|
||||||
comp::inventory::item::MaterialStatManifest,
|
|
||||||
};
|
|
||||||
use crossbeam_channel::{self, TryIter};
|
use crossbeam_channel::{self, TryIter};
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use rusqlite::Transaction;
|
use rusqlite::Transaction;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use tracing::{error, trace};
|
use tracing::{error, trace};
|
||||||
@ -83,13 +79,6 @@ pub struct CharacterLoader {
|
|||||||
update_tx: crossbeam_channel::Sender<CharacterLoaderRequest>,
|
update_tx: crossbeam_channel::Sender<CharacterLoaderRequest>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decoupled from the ECS resource because the plumbing is getting complicated;
|
|
||||||
// shouldn't matter unless someone's hot-reloading material stats on the live
|
|
||||||
// server
|
|
||||||
lazy_static! {
|
|
||||||
pub static ref MATERIAL_STATS_MANIFEST: MaterialStatManifest = MaterialStatManifest::default();
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CharacterLoader {
|
impl CharacterLoader {
|
||||||
pub fn new(settings: Arc<RwLock<DatabaseSettings>>) -> Result<Self, PersistenceError> {
|
pub fn new(settings: Arc<RwLock<DatabaseSettings>>) -> Result<Self, PersistenceError> {
|
||||||
let (update_tx, internal_rx) = crossbeam_channel::unbounded::<CharacterLoaderRequest>();
|
let (update_tx, internal_rx) = crossbeam_channel::unbounded::<CharacterLoaderRequest>();
|
||||||
@ -163,7 +152,6 @@ impl CharacterLoader {
|
|||||||
&character_alias,
|
&character_alias,
|
||||||
persisted_components,
|
persisted_components,
|
||||||
&mut transaction,
|
&mut transaction,
|
||||||
&MATERIAL_STATS_MANIFEST,
|
|
||||||
)),
|
)),
|
||||||
CharacterLoaderRequestKind::DeleteCharacter {
|
CharacterLoaderRequestKind::DeleteCharacter {
|
||||||
player_uuid,
|
player_uuid,
|
||||||
@ -172,25 +160,18 @@ impl CharacterLoader {
|
|||||||
&player_uuid,
|
&player_uuid,
|
||||||
character_id,
|
character_id,
|
||||||
&mut transaction,
|
&mut transaction,
|
||||||
&MATERIAL_STATS_MANIFEST,
|
|
||||||
)),
|
)),
|
||||||
CharacterLoaderRequestKind::LoadCharacterList { player_uuid } => {
|
CharacterLoaderRequestKind::LoadCharacterList { player_uuid } => {
|
||||||
CharacterLoaderResponseKind::CharacterList(load_character_list(
|
CharacterLoaderResponseKind::CharacterList(load_character_list(
|
||||||
&player_uuid,
|
&player_uuid,
|
||||||
&mut transaction,
|
&mut transaction,
|
||||||
&MATERIAL_STATS_MANIFEST,
|
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
CharacterLoaderRequestKind::LoadCharacterData {
|
CharacterLoaderRequestKind::LoadCharacterData {
|
||||||
player_uuid,
|
player_uuid,
|
||||||
character_id,
|
character_id,
|
||||||
} => {
|
} => {
|
||||||
let result = load_character_data(
|
let result = load_character_data(player_uuid, character_id, &mut transaction);
|
||||||
player_uuid,
|
|
||||||
character_id,
|
|
||||||
&mut transaction,
|
|
||||||
&MATERIAL_STATS_MANIFEST,
|
|
||||||
);
|
|
||||||
if result.is_err() {
|
if result.is_err() {
|
||||||
error!(
|
error!(
|
||||||
?result,
|
?result,
|
||||||
|
@ -2,9 +2,13 @@ use crate::comp;
|
|||||||
use common::character::CharacterId;
|
use common::character::CharacterId;
|
||||||
|
|
||||||
use crate::persistence::{
|
use crate::persistence::{
|
||||||
error::PersistenceError, establish_connection, DatabaseSettings, VelorenConnection,
|
character_loader::{CharacterLoaderResponse, CharacterLoaderResponseKind},
|
||||||
|
error::PersistenceError,
|
||||||
|
establish_connection, DatabaseSettings, VelorenConnection,
|
||||||
};
|
};
|
||||||
|
use crossbeam_channel::TryIter;
|
||||||
use rusqlite::DropBehavior;
|
use rusqlite::DropBehavior;
|
||||||
|
use specs::Entity;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
sync::{
|
sync::{
|
||||||
@ -18,6 +22,11 @@ pub type CharacterUpdateData = (comp::SkillSet, comp::Inventory, Option<comp::Wa
|
|||||||
|
|
||||||
pub enum CharacterUpdaterEvent {
|
pub enum CharacterUpdaterEvent {
|
||||||
BatchUpdate(Vec<(CharacterId, CharacterUpdateData)>),
|
BatchUpdate(Vec<(CharacterId, CharacterUpdateData)>),
|
||||||
|
DeleteCharacter {
|
||||||
|
entity: Entity,
|
||||||
|
requesting_player_uuid: String,
|
||||||
|
character_id: CharacterId,
|
||||||
|
},
|
||||||
DisconnectedSuccess,
|
DisconnectedSuccess,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,6 +37,7 @@ pub enum CharacterUpdaterEvent {
|
|||||||
/// such as inventory, loadout, etc...
|
/// such as inventory, loadout, etc...
|
||||||
pub struct CharacterUpdater {
|
pub struct CharacterUpdater {
|
||||||
update_tx: Option<crossbeam_channel::Sender<CharacterUpdaterEvent>>,
|
update_tx: Option<crossbeam_channel::Sender<CharacterUpdaterEvent>>,
|
||||||
|
response_rx: crossbeam_channel::Receiver<CharacterLoaderResponse>,
|
||||||
handle: Option<std::thread::JoinHandle<()>>,
|
handle: Option<std::thread::JoinHandle<()>>,
|
||||||
pending_logout_updates: HashMap<CharacterId, CharacterUpdateData>,
|
pending_logout_updates: HashMap<CharacterId, CharacterUpdateData>,
|
||||||
/// Will disconnect all characters (without persistence) on the next tick if
|
/// Will disconnect all characters (without persistence) on the next tick if
|
||||||
@ -38,6 +48,8 @@ pub struct CharacterUpdater {
|
|||||||
impl CharacterUpdater {
|
impl CharacterUpdater {
|
||||||
pub fn new(settings: Arc<RwLock<DatabaseSettings>>) -> rusqlite::Result<Self> {
|
pub fn new(settings: Arc<RwLock<DatabaseSettings>>) -> rusqlite::Result<Self> {
|
||||||
let (update_tx, update_rx) = crossbeam_channel::unbounded::<CharacterUpdaterEvent>();
|
let (update_tx, update_rx) = crossbeam_channel::unbounded::<CharacterUpdaterEvent>();
|
||||||
|
let (response_tx, response_rx) = crossbeam_channel::unbounded::<CharacterLoaderResponse>();
|
||||||
|
|
||||||
let disconnect_all_clients_requested = Arc::new(AtomicBool::new(false));
|
let disconnect_all_clients_requested = Arc::new(AtomicBool::new(false));
|
||||||
let disconnect_all_clients_requested_clone = Arc::clone(&disconnect_all_clients_requested);
|
let disconnect_all_clients_requested_clone = Arc::clone(&disconnect_all_clients_requested);
|
||||||
|
|
||||||
@ -68,6 +80,33 @@ impl CharacterUpdater {
|
|||||||
.store(true, Ordering::Relaxed);
|
.store(true, Ordering::Relaxed);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
CharacterUpdaterEvent::DeleteCharacter {
|
||||||
|
entity,
|
||||||
|
requesting_player_uuid,
|
||||||
|
character_id,
|
||||||
|
} => {
|
||||||
|
match execute_character_delete(
|
||||||
|
entity,
|
||||||
|
&requesting_player_uuid,
|
||||||
|
character_id,
|
||||||
|
&mut conn,
|
||||||
|
) {
|
||||||
|
Ok(response) => {
|
||||||
|
if let Err(e) = response_tx.send(response) {
|
||||||
|
error!(?e, "Could not send character deletion response");
|
||||||
|
} else {
|
||||||
|
debug!(
|
||||||
|
"Processed character delete for character ID {}",
|
||||||
|
character_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => error!(
|
||||||
|
"Error deleting character ID {}, error: {:?}",
|
||||||
|
character_id, e
|
||||||
|
),
|
||||||
|
}
|
||||||
|
},
|
||||||
CharacterUpdaterEvent::DisconnectedSuccess => {
|
CharacterUpdaterEvent::DisconnectedSuccess => {
|
||||||
info!(
|
info!(
|
||||||
"CharacterUpdater received DisconnectedSuccess event, resuming \
|
"CharacterUpdater received DisconnectedSuccess event, resuming \
|
||||||
@ -84,6 +123,7 @@ impl CharacterUpdater {
|
|||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
update_tx: Some(update_tx),
|
update_tx: Some(update_tx),
|
||||||
|
response_rx,
|
||||||
handle: Some(handle),
|
handle: Some(handle),
|
||||||
pending_logout_updates: HashMap::new(),
|
pending_logout_updates: HashMap::new(),
|
||||||
disconnect_all_clients_requested,
|
disconnect_all_clients_requested,
|
||||||
@ -125,6 +165,32 @@ impl CharacterUpdater {
|
|||||||
.load(Ordering::Relaxed)
|
.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn delete_character(
|
||||||
|
&mut self,
|
||||||
|
entity: Entity,
|
||||||
|
requesting_player_uuid: String,
|
||||||
|
character_id: CharacterId,
|
||||||
|
) {
|
||||||
|
if let Err(e) =
|
||||||
|
self.update_tx
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.send(CharacterUpdaterEvent::DeleteCharacter {
|
||||||
|
entity,
|
||||||
|
requesting_player_uuid,
|
||||||
|
character_id,
|
||||||
|
})
|
||||||
|
{
|
||||||
|
error!(?e, "Could not send character deletion request");
|
||||||
|
} else {
|
||||||
|
// Once a delete request has been sent to the channel we must remove any pending
|
||||||
|
// updates for the character in the event that it has recently logged out.
|
||||||
|
// Since the user has actively chosen to delete the character there is no value
|
||||||
|
// in the pending update data anyway.
|
||||||
|
self.pending_logout_updates.remove(&character_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Updates a collection of characters based on their id and components
|
/// Updates a collection of characters based on their id and components
|
||||||
pub fn batch_update<'a>(
|
pub fn batch_update<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -185,6 +251,9 @@ impl CharacterUpdater {
|
|||||||
future persistence batches from running",
|
future persistence batches from running",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a non-blocking iterator over CharacterLoaderResponse messages
|
||||||
|
pub fn messages(&self) -> TryIter<CharacterLoaderResponse> { self.response_rx.try_iter() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute_batch_update(
|
fn execute_batch_update(
|
||||||
@ -205,6 +274,30 @@ fn execute_batch_update(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn execute_character_delete(
|
||||||
|
entity: Entity,
|
||||||
|
requesting_player_uuid: &str,
|
||||||
|
character_id: CharacterId,
|
||||||
|
connection: &mut VelorenConnection,
|
||||||
|
) -> Result<CharacterLoaderResponse, PersistenceError> {
|
||||||
|
let mut transaction = connection.connection.transaction()?;
|
||||||
|
|
||||||
|
let response = CharacterLoaderResponse {
|
||||||
|
entity,
|
||||||
|
result: CharacterLoaderResponseKind::CharacterList(super::character::delete_character(
|
||||||
|
requesting_player_uuid,
|
||||||
|
character_id,
|
||||||
|
&mut transaction,
|
||||||
|
)),
|
||||||
|
};
|
||||||
|
|
||||||
|
if !response.is_err() {
|
||||||
|
transaction.commit()?;
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(response)
|
||||||
|
}
|
||||||
|
|
||||||
impl Drop for CharacterUpdater {
|
impl Drop for CharacterUpdater {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
drop(self.update_tx.take());
|
drop(self.update_tx.take());
|
||||||
|
@ -13,7 +13,7 @@ use common::{
|
|||||||
};
|
};
|
||||||
use common_ecs::{Job, Origin, Phase, System};
|
use common_ecs::{Job, Origin, Phase, System};
|
||||||
use common_net::msg::{ClientGeneral, ServerGeneral};
|
use common_net::msg::{ClientGeneral, ServerGeneral};
|
||||||
use specs::{Entities, Join, Read, ReadExpect, ReadStorage};
|
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, WriteExpect};
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use tracing::{debug, warn};
|
use tracing::{debug, warn};
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ impl Sys {
|
|||||||
entity: specs::Entity,
|
entity: specs::Entity,
|
||||||
client: &Client,
|
client: &Client,
|
||||||
character_loader: &ReadExpect<'_, CharacterLoader>,
|
character_loader: &ReadExpect<'_, CharacterLoader>,
|
||||||
character_updater: &ReadExpect<'_, CharacterUpdater>,
|
character_updater: &mut WriteExpect<'_, CharacterUpdater>,
|
||||||
uids: &ReadStorage<'_, Uid>,
|
uids: &ReadStorage<'_, Uid>,
|
||||||
players: &ReadStorage<'_, Player>,
|
players: &ReadStorage<'_, Player>,
|
||||||
presences: &ReadStorage<'_, Presence>,
|
presences: &ReadStorage<'_, Presence>,
|
||||||
@ -132,7 +132,7 @@ impl Sys {
|
|||||||
},
|
},
|
||||||
ClientGeneral::DeleteCharacter(character_id) => {
|
ClientGeneral::DeleteCharacter(character_id) => {
|
||||||
if let Some(player) = players.get(entity) {
|
if let Some(player) = players.get(entity) {
|
||||||
character_loader.delete_character(
|
character_updater.delete_character(
|
||||||
entity,
|
entity,
|
||||||
player.uuid().to_string(),
|
player.uuid().to_string(),
|
||||||
character_id,
|
character_id,
|
||||||
@ -154,7 +154,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
Entities<'a>,
|
Entities<'a>,
|
||||||
Read<'a, EventBus<ServerEvent>>,
|
Read<'a, EventBus<ServerEvent>>,
|
||||||
ReadExpect<'a, CharacterLoader>,
|
ReadExpect<'a, CharacterLoader>,
|
||||||
ReadExpect<'a, CharacterUpdater>,
|
WriteExpect<'a, CharacterUpdater>,
|
||||||
ReadStorage<'a, Uid>,
|
ReadStorage<'a, Uid>,
|
||||||
ReadStorage<'a, Client>,
|
ReadStorage<'a, Client>,
|
||||||
ReadStorage<'a, Player>,
|
ReadStorage<'a, Player>,
|
||||||
@ -173,7 +173,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entities,
|
entities,
|
||||||
server_event_bus,
|
server_event_bus,
|
||||||
character_loader,
|
character_loader,
|
||||||
character_updater,
|
mut character_updater,
|
||||||
uids,
|
uids,
|
||||||
clients,
|
clients,
|
||||||
players,
|
players,
|
||||||
@ -191,7 +191,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
entity,
|
entity,
|
||||||
client,
|
client,
|
||||||
&character_loader,
|
&character_loader,
|
||||||
&character_updater,
|
&mut character_updater,
|
||||||
&uids,
|
&uids,
|
||||||
&players,
|
&players,
|
||||||
&presences,
|
&presences,
|
||||||
|
Loading…
Reference in New Issue
Block a user