mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix group chat leak
This commit is contained in:
parent
19742bb930
commit
ec92b2c33b
@ -346,10 +346,10 @@ impl<G> GenericChatMsg<G> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_group(&self) -> Option<&G> {
|
||||
match &self.chat_type {
|
||||
ChatType::GroupMeta(g) => Some(g),
|
||||
ChatType::Group(_, g) => Some(g),
|
||||
pub fn get_group_mut_sender(&mut self) -> Option<(&mut G, Option<&Uid>)> {
|
||||
match &mut self.chat_type {
|
||||
ChatType::GroupMeta(g) => Some((g, None)),
|
||||
ChatType::Group(sender, g) => Some((g, Some(sender))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -908,22 +908,46 @@ impl StateExt for State {
|
||||
|
||||
/// Send the chat message to the proper players. Say and region are limited
|
||||
/// by location. Faction and group are limited by component.
|
||||
fn send_chat(&self, msg: comp::UnresolvedChatMsg) {
|
||||
fn send_chat(&self, mut msg: comp::UnresolvedChatMsg) {
|
||||
let ecs = self.ecs();
|
||||
let is_within =
|
||||
|target, a: &comp::Pos, b: &comp::Pos| a.0.distance_squared(b.0) < target * target;
|
||||
|
||||
let id_maps = ecs.read_resource::<IdMaps>();
|
||||
let entity_from_uid = |uid| id_maps.uid_entity(uid);
|
||||
|
||||
let group_manager = ecs.read_resource::<comp::group::GroupManager>();
|
||||
|
||||
let group_info = msg.get_group().and_then(|g| group_manager.group_info(*g));
|
||||
let group_info = msg.get_group_mut_sender().and_then(|(g, from)| {
|
||||
// Check if the sender is in the group he is trying to send the message to. If
|
||||
// it doesn't match, update the message's group accordingly.
|
||||
// There currently is a bug that can cause group messages to appear in other
|
||||
// groups. This commonly happens when a player has his [ChatMode] set
|
||||
// to group and is kicked from his current group or joins another,
|
||||
// any message sent afterwards appears in the previous group as long
|
||||
// as his chatmode isn't updated.
|
||||
// TODO: Find out why sometimes messages from players never previously in the
|
||||
// group leak.
|
||||
// FIXME: Another pontential fix could be updating the [ChatMode] as the player
|
||||
// leaves and joins a new group. Possibly a better solution?
|
||||
if let Some(from) = from {
|
||||
let group = ecs
|
||||
.read_storage::<comp::Group>()
|
||||
.get(entity_from_uid(*from)?)
|
||||
.copied()?;
|
||||
|
||||
if g != &group {
|
||||
*g = group;
|
||||
}
|
||||
}
|
||||
|
||||
group_manager.group_info(*g)
|
||||
});
|
||||
|
||||
let resolved_msg = msg
|
||||
.clone()
|
||||
.map_group(|_| group_info.map_or_else(|| "???".to_string(), |i| i.name.clone()));
|
||||
|
||||
let id_maps = ecs.read_resource::<IdMaps>();
|
||||
let entity_from_uid = |uid| id_maps.uid_entity(uid);
|
||||
|
||||
if msg.chat_type.uid().map_or(true, |sender| {
|
||||
entity_from_uid(sender).map_or(false, |e| {
|
||||
self.validate_chat_msg(
|
||||
@ -1082,16 +1106,15 @@ impl StateExt for State {
|
||||
/region to change chat.",
|
||||
);
|
||||
|
||||
if let Some((client, _)) =
|
||||
(&ecs.read_storage::<Client>(), &ecs.read_storage::<Uid>())
|
||||
.join()
|
||||
.find(|(_, uid)| *uid == from)
|
||||
let clients = ecs.read_storage::<Client>();
|
||||
if let Some(client) =
|
||||
entity_from_uid(*from).and_then(|entity| clients.get(entity))
|
||||
{
|
||||
client.send_fallible(ServerGeneral::ChatMsg(reply));
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
send_to_group(g, ecs, &resolved_msg);
|
||||
}
|
||||
send_to_group(g, ecs, &resolved_msg);
|
||||
},
|
||||
comp::ChatType::GroupMeta(g) => {
|
||||
send_to_group(g, ecs, &resolved_msg);
|
||||
|
Loading…
Reference in New Issue
Block a user