mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
fix chat-cli name formatting.
This commit is contained in:
parent
4117f2f2a8
commit
aabf9d7b21
@ -84,8 +84,7 @@ fn main() {
|
||||
|
||||
for event in events {
|
||||
match event {
|
||||
// TODO client is now responsible for formatting the `[{player_name}] {}`
|
||||
Event::Chat(m) => println!("{}", m.message),
|
||||
Event::Chat(m) => println!("{}", client.format_message(&m)),
|
||||
Event::Disconnect => {}, // TODO
|
||||
Event::DisconnectionNotification(time) => {
|
||||
let message = match time {
|
||||
|
@ -1007,6 +1007,50 @@ impl Client {
|
||||
|
||||
self.entity = entity_builder.with(uid).build();
|
||||
}
|
||||
|
||||
/// Format a message for the client (voxygen chat box or chat-cli)
|
||||
pub fn format_message(&self, comp::ChatMsg { chat_type, message }: &comp::ChatMsg) -> String {
|
||||
let alias_of_uid = |uid| {
|
||||
self.player_list
|
||||
.get(uid)
|
||||
.map_or("<?>".to_string(), |player_info| {
|
||||
if player_info.is_admin {
|
||||
format!("ADMIN - {}", player_info.player_alias)
|
||||
} else {
|
||||
player_info.player_alias.to_string()
|
||||
}
|
||||
})
|
||||
};
|
||||
let message_format = |uid, message, group| {
|
||||
if let Some(group) = group {
|
||||
format!("{{{}}} [{}]: {}", group, alias_of_uid(uid), message)
|
||||
} else {
|
||||
format!("[{}]: {}", alias_of_uid(uid), message)
|
||||
}
|
||||
};
|
||||
match chat_type {
|
||||
comp::ChatType::Private => message.to_string(),
|
||||
comp::ChatType::Broadcast => message.to_string(),
|
||||
comp::ChatType::Kill => message.to_string(),
|
||||
comp::ChatType::Tell(from, to) => {
|
||||
let from_alias = alias_of_uid(from);
|
||||
let to_alias = alias_of_uid(to);
|
||||
if Some(from) == self.state.ecs().read_storage::<Uid>().get(self.entity) {
|
||||
format!("To [{}]: {}", to_alias, message)
|
||||
} else {
|
||||
format!("From [{}]: {}", from_alias, message)
|
||||
}
|
||||
},
|
||||
comp::ChatType::Say(uid) => message_format(uid, message, None),
|
||||
comp::ChatType::Group(uid, s) => message_format(uid, message, Some(s)),
|
||||
comp::ChatType::Faction(uid, s) => message_format(uid, message, Some(s)),
|
||||
comp::ChatType::Region(uid) => message_format(uid, message, None),
|
||||
comp::ChatType::World(uid) => message_format(uid, message, None),
|
||||
// NPCs can't talk. Should be filtered by hud/mod.rs for voxygen and should be filtered
|
||||
// by server for chat-cli
|
||||
comp::ChatType::Npc(_uid, _r) => "".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Client {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{path::Chaser, state::Time};
|
||||
use crate::path::Chaser;
|
||||
use specs::{Component, Entity as EcsEntity};
|
||||
use specs_idvs::IDVStorage;
|
||||
use vek::*;
|
||||
@ -107,47 +107,3 @@ impl Activity {
|
||||
impl Default for Activity {
|
||||
fn default() -> Self { Activity::Idle(Vec2::zero()) }
|
||||
}
|
||||
|
||||
/// Default duration in seconds of speech bubbles
|
||||
pub const SPEECH_BUBBLE_DURATION: f64 = 5.0;
|
||||
|
||||
/// The contents of a speech bubble
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum SpeechBubbleMessage {
|
||||
/// This message was said by a player and needs no translation
|
||||
Plain(String),
|
||||
/// This message was said by an NPC. The fields are a i18n key and a random
|
||||
/// u16 index
|
||||
Localized(String, u16),
|
||||
}
|
||||
|
||||
/// Adds a speech bubble to the entity
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct SpeechBubble {
|
||||
pub message: SpeechBubbleMessage,
|
||||
pub timeout: Option<Time>,
|
||||
// TODO add icon enum for player chat type / npc quest+trade
|
||||
}
|
||||
impl SpeechBubble {
|
||||
pub fn npc_new(i18n_key: String, now: Time) -> Self {
|
||||
let message = SpeechBubbleMessage::Localized(i18n_key, rand::random());
|
||||
let timeout = Some(Time(now.0 + SPEECH_BUBBLE_DURATION));
|
||||
Self { message, timeout }
|
||||
}
|
||||
|
||||
pub fn player_new(message: String, now: Time) -> Self {
|
||||
let message = SpeechBubbleMessage::Plain(message);
|
||||
let timeout = Some(Time(now.0 + SPEECH_BUBBLE_DURATION));
|
||||
Self { message, timeout }
|
||||
}
|
||||
|
||||
pub fn message<F>(&self, i18n_variation: F) -> String
|
||||
where
|
||||
F: Fn(String, u16) -> String,
|
||||
{
|
||||
match &self.message {
|
||||
SpeechBubbleMessage::Plain(m) => m.to_string(),
|
||||
SpeechBubbleMessage::Localized(k, i) => i18n_variation(k.to_string(), *i),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ fn main() {
|
||||
|
||||
// Load settings
|
||||
let settings = ServerSettings::load();
|
||||
let server_port = &settings.gameserver_address.port();
|
||||
let metrics_port = &settings.metrics_address.port();
|
||||
|
||||
// Create server
|
||||
@ -31,6 +32,7 @@ fn main() {
|
||||
|
||||
info!("Server is ready to accept connections.");
|
||||
info!(?metrics_port, "starting metrics at port");
|
||||
info!(?server_port, "starting server at port");
|
||||
|
||||
loop {
|
||||
let events = server
|
||||
|
@ -18,7 +18,6 @@ use conrod_core::{
|
||||
widget::{self, Button, Id, Image, List, Rectangle, Text, TextEdit},
|
||||
widget_ids, Color, Colorable, Positionable, Sizeable, Ui, UiCell, Widget, WidgetCommon,
|
||||
};
|
||||
use specs::world::WorldExt;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
widget_ids! {
|
||||
@ -35,6 +34,7 @@ widget_ids! {
|
||||
const MAX_MESSAGES: usize = 100;
|
||||
|
||||
const CHAT_BOX_WIDTH: f64 = 470.0;
|
||||
const CHAT_BOX_INPUT_WIDTH: f64 = 460.0;
|
||||
const CHAT_BOX_HEIGHT: f64 = 174.0;
|
||||
|
||||
#[derive(WidgetCommon)]
|
||||
@ -279,7 +279,7 @@ impl<'a> Widget for Chat<'a> {
|
||||
// Any changes to this TextEdit's width and font size must be reflected in
|
||||
// `cursor_offset_to_index` below.
|
||||
let mut text_edit = TextEdit::new(&state.input)
|
||||
.w(460.0)
|
||||
.w(CHAT_BOX_INPUT_WIDTH)
|
||||
.restrict_to_height(false)
|
||||
.color(TEXT_COLOR)
|
||||
.line_spacing(2.0)
|
||||
@ -340,8 +340,9 @@ impl<'a> Widget for Chat<'a> {
|
||||
while let Some(item) = items.next(ui) {
|
||||
// This would be easier if conrod used the v-metrics from rusttype.
|
||||
if item.i < state.messages.len() {
|
||||
let (color, msg, icon) =
|
||||
render_chat_line(&state.messages[item.i], &self.imgs, &self.client);
|
||||
let message = &state.messages[item.i];
|
||||
let (color, icon) = render_chat_line(&message.chat_type, &self.imgs);
|
||||
let msg = self.client.format_message(message);
|
||||
let text = Text::new(&msg)
|
||||
.font_size(self.fonts.opensans.scale(15))
|
||||
.font_id(self.fonts.opensans.conrod_id)
|
||||
@ -471,99 +472,27 @@ fn cursor_offset_to_index(
|
||||
fonts: &ConrodVoxygenFonts,
|
||||
) -> Option<Index> {
|
||||
// This moves the cursor to the given offset. Conrod is a pain.
|
||||
//let iter = cursor::xys_per_line_from_text(&text, &[], &font, font_size,
|
||||
// Justify::Left, Align::Start, 2.0, Rect{x: Range{start: 0.0, end: width}, y:
|
||||
// Range{start: 0.0, end: 12.345}});
|
||||
// cursor::closest_cursor_index_and_xy([f64::MAX, f64::MAX], iter).map(|(i, _)|
|
||||
// i) Width and font must match that of the chat TextEdit
|
||||
let width = 460.0;
|
||||
//
|
||||
// Width and font must match that of the chat TextEdit
|
||||
let font = ui.fonts.get(fonts.opensans.conrod_id)?;
|
||||
let font_size = fonts.opensans.scale(15);
|
||||
let infos = text::line::infos(&text, &font, font_size).wrap_by_whitespace(width);
|
||||
let infos = text::line::infos(&text, &font, font_size).wrap_by_whitespace(CHAT_BOX_INPUT_WIDTH);
|
||||
|
||||
cursor::index_before_char(infos, offset)
|
||||
}
|
||||
|
||||
fn render_chat_line(
|
||||
ChatMsg { chat_type, message }: &ChatMsg,
|
||||
imgs: &Imgs,
|
||||
client: &Client,
|
||||
) -> (Color, String, conrod_core::image::Id) {
|
||||
let alias_of_uid = |uid| {
|
||||
client
|
||||
.player_list
|
||||
.get(uid)
|
||||
.map_or("<?>".to_string(), |player_info| {
|
||||
if player_info.is_admin {
|
||||
format!("ADMIN - {}", player_info.player_alias)
|
||||
} else {
|
||||
player_info.player_alias.to_string()
|
||||
}
|
||||
})
|
||||
};
|
||||
let message_format = |uid, message, group| {
|
||||
if let Some(group) = group {
|
||||
format!("{{{}}} [{}]: {}", group, alias_of_uid(uid), message)
|
||||
} else {
|
||||
format!("[{}]: {}", alias_of_uid(uid), message)
|
||||
}
|
||||
};
|
||||
/// Get the color and icon for the current line in the chat box
|
||||
fn render_chat_line(chat_type: &ChatType, imgs: &Imgs) -> (Color, conrod_core::image::Id) {
|
||||
match chat_type {
|
||||
ChatType::Private => (PRIVATE_COLOR, message.to_string(), imgs.chat_private_small),
|
||||
ChatType::Broadcast => (
|
||||
BROADCAST_COLOR,
|
||||
message.to_string(),
|
||||
imgs.chat_broadcast_small,
|
||||
),
|
||||
ChatType::Kill => (KILL_COLOR, message.to_string(), imgs.chat_kill_small),
|
||||
ChatType::Tell(from, to) => {
|
||||
let from_alias = alias_of_uid(&from);
|
||||
let to_alias = alias_of_uid(&to);
|
||||
if Some(from)
|
||||
== client
|
||||
.state()
|
||||
.ecs()
|
||||
.read_storage::<common::sync::Uid>()
|
||||
.get(client.entity())
|
||||
{
|
||||
(
|
||||
TELL_COLOR,
|
||||
format!("To [{}]: {}", to_alias, message),
|
||||
imgs.chat_tell_small,
|
||||
)
|
||||
} else {
|
||||
(
|
||||
TELL_COLOR,
|
||||
format!("From [{}]: {}", from_alias, message),
|
||||
imgs.chat_tell_small,
|
||||
)
|
||||
}
|
||||
},
|
||||
ChatType::Say(uid) => (
|
||||
SAY_COLOR,
|
||||
message_format(uid, message, None),
|
||||
imgs.chat_say_small,
|
||||
),
|
||||
ChatType::Group(uid, s) => (
|
||||
GROUP_COLOR,
|
||||
message_format(uid, message, Some(s)),
|
||||
imgs.chat_group_small,
|
||||
),
|
||||
ChatType::Faction(uid, s) => (
|
||||
FACTION_COLOR,
|
||||
message_format(uid, message, Some(s)),
|
||||
imgs.chat_faction_small,
|
||||
),
|
||||
ChatType::Region(uid) => (
|
||||
REGION_COLOR,
|
||||
message_format(uid, message, None),
|
||||
imgs.chat_region_small,
|
||||
),
|
||||
ChatType::World(uid) => (
|
||||
WORLD_COLOR,
|
||||
message_format(uid, message, None),
|
||||
imgs.chat_world_small,
|
||||
),
|
||||
ChatType::Private => (PRIVATE_COLOR, imgs.chat_private_small),
|
||||
ChatType::Broadcast => (BROADCAST_COLOR, imgs.chat_broadcast_small),
|
||||
ChatType::Kill => (KILL_COLOR, imgs.chat_kill_small),
|
||||
ChatType::Tell(_from, _to) => (TELL_COLOR, imgs.chat_tell_small),
|
||||
ChatType::Say(_uid) => (SAY_COLOR, imgs.chat_say_small),
|
||||
ChatType::Group(_uid, _s) => (GROUP_COLOR, imgs.chat_group_small),
|
||||
ChatType::Faction(_uid, _s) => (FACTION_COLOR, imgs.chat_faction_small),
|
||||
ChatType::Region(_uid) => (REGION_COLOR, imgs.chat_region_small),
|
||||
ChatType::World(_uid) => (WORLD_COLOR, imgs.chat_world_small),
|
||||
ChatType::Npc(_uid, _r) => panic!("NPCs can't talk"), // Should be filtered by hud/mod.rs
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user