mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
* Fixed character load errors not being handled in Voxygen.
* Improved server error message for character load errors. * Added server logging for item asset load errors during character load. * Fixed character select error message dialog not supporting long messages.
This commit is contained in:
parent
d2a7aa34b1
commit
5636083e27
@ -493,13 +493,18 @@ impl Client {
|
||||
{
|
||||
const C_TYPE: ClientType = ClientType::Game;
|
||||
let verified = msg.verify(C_TYPE, self.registered, self.presence);
|
||||
assert!(
|
||||
verified,
|
||||
format!(
|
||||
"c_type: {:?}, registered: {}, presence: {:?}, msg: {:?}",
|
||||
C_TYPE, self.registered, self.presence, msg
|
||||
)
|
||||
);
|
||||
|
||||
// Due to the fact that character loading is performed asynchronously after
|
||||
// initial connect it is possible to receive messages after a character load
|
||||
// error while in the wrong state.
|
||||
if !verified {
|
||||
warn!(
|
||||
"Received ClientType::Game message when not in game (Registered: {} Presence: \
|
||||
{:?}), dropping message: {:?} ",
|
||||
self.registered, self.presence, msg
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
match msg {
|
||||
ClientMsg::Type(msg) => self.register_stream.send(msg),
|
||||
|
@ -212,7 +212,7 @@ pub fn convert_stats_to_database(
|
||||
pub fn convert_inventory_from_database_items(database_items: &[Item]) -> Result<Inventory, Error> {
|
||||
let mut inventory = Inventory::new_empty();
|
||||
for db_item in database_items.iter() {
|
||||
let mut item = common::comp::Item::new_from_asset(db_item.item_definition_id.as_str())?;
|
||||
let mut item = get_item_from_asset(db_item.item_definition_id.as_str())?;
|
||||
|
||||
// NOTE: Since this is freshly loaded, the atomic is *unique.*
|
||||
let comp = item.get_item_id_for_database();
|
||||
@ -269,7 +269,7 @@ pub fn convert_loadout_from_database_items(
|
||||
) -> Result<Loadout, Error> {
|
||||
let mut loadout = loadout_builder::LoadoutBuilder::new();
|
||||
for db_item in database_items.iter() {
|
||||
let item = common::comp::Item::new_from_asset(db_item.item_definition_id.as_str())?;
|
||||
let item = get_item_from_asset(db_item.item_definition_id.as_str())?;
|
||||
// NOTE: item id is currently *unique*, so we can store the ID safely.
|
||||
let comp = item.get_item_id_for_database();
|
||||
comp.store(Some(NonZeroU64::try_from(db_item.item_id as u64).map_err(
|
||||
@ -365,3 +365,13 @@ pub fn convert_stats_from_database(stats: &Stats, alias: String) -> common::comp
|
||||
|
||||
new_stats
|
||||
}
|
||||
|
||||
fn get_item_from_asset(item_definition_id: &str) -> Result<common::comp::Item, Error> {
|
||||
common::comp::Item::new_from_asset(item_definition_id).map_err(|err| {
|
||||
Error::AssetError(format!(
|
||||
"Error loading item asset: {} - {}",
|
||||
item_definition_id,
|
||||
err.to_string()
|
||||
))
|
||||
})
|
||||
}
|
||||
|
@ -115,11 +115,19 @@ impl CharacterLoader {
|
||||
CharacterLoaderRequestKind::LoadCharacterData {
|
||||
player_uuid,
|
||||
character_id,
|
||||
} => CharacterLoaderResponseKind::CharacterData(Box::new(
|
||||
conn.transaction(|txn| {
|
||||
} => {
|
||||
let result = conn.transaction(|txn| {
|
||||
load_character_data(player_uuid, character_id, txn, &map)
|
||||
}),
|
||||
)),
|
||||
});
|
||||
if result.is_err() {
|
||||
error!(
|
||||
?result,
|
||||
"Error loading character data for character_id: {}",
|
||||
character_id
|
||||
);
|
||||
}
|
||||
CharacterLoaderResponseKind::CharacterData(Box::new(result))
|
||||
},
|
||||
},
|
||||
})
|
||||
{
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
extern crate diesel;
|
||||
|
||||
use common::assets::Error as AssetsError;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -40,10 +39,6 @@ impl fmt::Display for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<AssetsError> for Error {
|
||||
fn from(error: AssetsError) -> Error { Error::AssetError(error.to_string()) }
|
||||
}
|
||||
|
||||
impl From<diesel::result::Error> for Error {
|
||||
fn from(error: diesel::result::Error) -> Error { Error::DatabaseError(error) }
|
||||
}
|
||||
|
@ -55,6 +55,10 @@ pub struct GlobalState {
|
||||
// TODO: redo this so that the watcher doesn't have to exist for reloading to occur
|
||||
pub i18n: AssetHandle<Localization>,
|
||||
pub clipboard: Option<iced_winit::Clipboard>,
|
||||
// NOTE: This can be removed from GlobalState if client state behavior is refactored to not
|
||||
// enter the game before confirmation of successful character load
|
||||
/// An error returned by Client that needs to be displayed by the UI
|
||||
pub client_error: Option<String>,
|
||||
}
|
||||
|
||||
impl GlobalState {
|
||||
|
@ -188,6 +188,7 @@ fn main() {
|
||||
singleplayer: None,
|
||||
i18n,
|
||||
clipboard,
|
||||
client_error: None,
|
||||
};
|
||||
|
||||
run::run(global_state, event_loop);
|
||||
|
@ -11,7 +11,7 @@ use crate::{
|
||||
use client::{self, Client};
|
||||
use common::{comp, resources::DeltaTime, span};
|
||||
use specs::WorldExt;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
use std::{cell::RefCell, mem, rc::Rc};
|
||||
use tracing::error;
|
||||
use ui::CharSelectionUi;
|
||||
|
||||
@ -188,7 +188,7 @@ impl PlayState for CharSelectionState {
|
||||
self.char_selection_ui.select_character(character_id);
|
||||
},
|
||||
client::Event::CharacterError(error) => {
|
||||
self.char_selection_ui.display_error(error);
|
||||
global_state.client_error = Some(error);
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
@ -202,6 +202,10 @@ impl PlayState for CharSelectionState {
|
||||
},
|
||||
}
|
||||
|
||||
if let Some(error) = mem::take(&mut global_state.client_error) {
|
||||
self.char_selection_ui.display_error(error);
|
||||
}
|
||||
|
||||
// TODO: make sure rendering is not relying on cleaned up stuff
|
||||
self.client.borrow_mut().cleanup();
|
||||
|
||||
@ -213,7 +217,7 @@ impl PlayState for CharSelectionState {
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str { "Title" }
|
||||
fn name(&self) -> &'static str { "Character Selection" }
|
||||
|
||||
fn render(&mut self, renderer: &mut Renderer, _: &Settings) {
|
||||
let client = self.client.borrow();
|
||||
|
@ -656,13 +656,13 @@ impl Controls {
|
||||
},
|
||||
InfoContent::CharacterError(error) => Column::with_children(vec![
|
||||
Text::new(error).size(fonts.cyri.scale(24)).into(),
|
||||
Container::new(neat_button(
|
||||
Row::with_children(vec![neat_button(
|
||||
no_button,
|
||||
i18n.get("common.close"),
|
||||
FILL_FRAC_ONE,
|
||||
button_style,
|
||||
Some(Message::ClearCharacterListError),
|
||||
))
|
||||
)])
|
||||
.height(Length::Units(28))
|
||||
.into(),
|
||||
])
|
||||
@ -679,11 +679,11 @@ impl Controls {
|
||||
(28, 28, 22, 255).into(),
|
||||
),
|
||||
)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.width(Length::Shrink)
|
||||
.height(Length::Shrink)
|
||||
.max_width(400)
|
||||
.max_height(130)
|
||||
.padding(16)
|
||||
.max_height(500)
|
||||
.padding(24)
|
||||
.center_x()
|
||||
.center_y();
|
||||
|
||||
|
@ -181,7 +181,9 @@ impl SessionState {
|
||||
},
|
||||
client::Event::Outcome(outcome) => outcomes.push(outcome),
|
||||
client::Event::CharacterCreated(_) => {},
|
||||
client::Event::CharacterError(_) => {},
|
||||
client::Event::CharacterError(error) => {
|
||||
global_state.client_error = Some(error);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user