2020-04-26 17:03:19 +00:00
|
|
|
use crate::{client::Client, Server};
|
|
|
|
use common::{
|
|
|
|
comp::{
|
|
|
|
self,
|
2020-08-07 01:59:28 +00:00
|
|
|
group::{self, Group, GroupManager, Invite, PendingInvites},
|
2020-04-26 17:03:19 +00:00
|
|
|
ChatType, GroupManip,
|
|
|
|
},
|
2020-10-12 08:18:28 +00:00
|
|
|
msg::{InviteAnswer, ServerGeneral},
|
2020-04-26 17:03:19 +00:00
|
|
|
sync,
|
|
|
|
sync::WorldSyncExt,
|
|
|
|
};
|
|
|
|
use specs::world::WorldExt;
|
2020-08-07 01:59:28 +00:00
|
|
|
use std::time::{Duration, Instant};
|
|
|
|
use tracing::{error, warn};
|
|
|
|
|
|
|
|
/// Time before invite times out
|
|
|
|
const INVITE_TIMEOUT_DUR: Duration = Duration::from_secs(31);
|
|
|
|
/// Reduced duration shown to the client to help alleviate latency issues
|
|
|
|
const PRESENTED_INVITE_TIMEOUT_DUR: Duration = Duration::from_secs(30);
|
2020-04-26 17:03:19 +00:00
|
|
|
|
|
|
|
// TODO: turn chat messages into enums
|
|
|
|
pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupManip) {
|
2020-08-07 01:59:28 +00:00
|
|
|
let max_group_size = server.settings().max_player_group_size;
|
2020-04-26 17:03:19 +00:00
|
|
|
let state = server.state_mut();
|
|
|
|
|
|
|
|
match manip {
|
|
|
|
GroupManip::Invite(uid) => {
|
|
|
|
let mut clients = state.ecs().write_storage::<Client>();
|
|
|
|
let invitee = match state.ecs().entity_from_uid(uid.into()) {
|
|
|
|
Some(t) => t,
|
|
|
|
None => {
|
|
|
|
// Inform of failure
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-07-12 00:39:50 +00:00
|
|
|
ChatType::Meta
|
2020-08-05 11:29:42 +00:00
|
|
|
.server_msg("Invite failed, target does not exist.".to_owned()),
|
2020-07-12 00:39:50 +00:00
|
|
|
);
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
let uids = state.ecs().read_storage::<sync::Uid>();
|
2020-07-12 00:39:50 +00:00
|
|
|
|
|
|
|
// Check if entity is trying to invite themselves to a group
|
|
|
|
if uids
|
|
|
|
.get(entity)
|
|
|
|
.map_or(false, |inviter_uid| *inviter_uid == uid)
|
|
|
|
{
|
|
|
|
warn!("Entity tried to invite themselves into a group");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-07 01:59:28 +00:00
|
|
|
// Disallow inviting entity that is already in your group
|
|
|
|
let groups = state.ecs().read_storage::<Group>();
|
|
|
|
let group_manager = state.ecs().read_resource::<GroupManager>();
|
2020-08-07 05:00:09 +00:00
|
|
|
let already_in_same_group = groups.get(entity).map_or(false, |group| {
|
2020-08-07 01:59:28 +00:00
|
|
|
group_manager
|
|
|
|
.group_info(*group)
|
|
|
|
.map_or(false, |g| g.leader == entity)
|
|
|
|
&& groups.get(invitee) == Some(group)
|
2020-08-07 05:00:09 +00:00
|
|
|
});
|
|
|
|
if already_in_same_group {
|
2020-08-07 01:59:28 +00:00
|
|
|
// Inform of failure
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(ChatType::Meta.server_msg(
|
2020-08-07 01:59:28 +00:00
|
|
|
"Invite failed, can't invite someone already in your group".to_owned(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let mut pending_invites = state.ecs().write_storage::<PendingInvites>();
|
|
|
|
|
|
|
|
// Check if group max size is already reached
|
|
|
|
// Adding the current number of pending invites
|
2020-08-07 05:00:09 +00:00
|
|
|
let group_size_limit_reached = state
|
2020-08-07 01:59:28 +00:00
|
|
|
.ecs()
|
|
|
|
.read_storage()
|
|
|
|
.get(entity)
|
|
|
|
.copied()
|
|
|
|
.and_then(|group| {
|
|
|
|
// If entity is currently the leader of a full group then they can't invite
|
|
|
|
// anyone else
|
|
|
|
group_manager
|
|
|
|
.group_info(group)
|
|
|
|
.filter(|i| i.leader == entity)
|
|
|
|
.map(|i| i.num_members)
|
|
|
|
})
|
|
|
|
.unwrap_or(1) as usize
|
|
|
|
+ pending_invites.get(entity).map_or(0, |p| p.0.len())
|
2020-08-07 05:00:09 +00:00
|
|
|
>= max_group_size as usize;
|
|
|
|
if group_size_limit_reached {
|
2020-08-07 01:59:28 +00:00
|
|
|
// Inform inviter that they have reached the group size limit
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-08-07 01:59:28 +00:00
|
|
|
ChatType::Meta.server_msg(
|
|
|
|
"Invite failed, pending invites plus current group size have reached \
|
|
|
|
the group size limit"
|
|
|
|
.to_owned(),
|
|
|
|
),
|
|
|
|
);
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
2020-08-07 01:59:28 +00:00
|
|
|
return;
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
|
|
|
|
2020-08-07 01:59:28 +00:00
|
|
|
let agents = state.ecs().read_storage::<comp::Agent>();
|
|
|
|
let mut invites = state.ecs().write_storage::<Invite>();
|
|
|
|
|
|
|
|
if invites.contains(invitee) {
|
2020-04-26 17:03:19 +00:00
|
|
|
// Inform inviter that there is already an invite
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
ChatType::Meta
|
|
|
|
.server_msg("This player already has a pending invite.".to_owned()),
|
|
|
|
);
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
2020-08-07 01:59:28 +00:00
|
|
|
return;
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
|
|
|
|
2020-08-07 01:59:28 +00:00
|
|
|
let mut invite_sent = false;
|
|
|
|
// Returns true if insertion was succesful
|
|
|
|
let mut send_invite = || {
|
|
|
|
match invites.insert(invitee, group::Invite(entity)) {
|
|
|
|
Err(err) => {
|
|
|
|
error!("Failed to insert Invite component: {:?}", err);
|
|
|
|
false
|
2020-04-26 17:03:19 +00:00
|
|
|
},
|
2020-08-07 01:59:28 +00:00
|
|
|
Ok(_) => {
|
|
|
|
match pending_invites.entry(entity) {
|
|
|
|
Ok(entry) => {
|
|
|
|
entry
|
|
|
|
.or_insert_with(|| PendingInvites(Vec::new()))
|
|
|
|
.0
|
|
|
|
.push((invitee, Instant::now() + INVITE_TIMEOUT_DUR));
|
|
|
|
invite_sent = true;
|
|
|
|
true
|
|
|
|
},
|
|
|
|
Err(err) => {
|
|
|
|
error!(
|
|
|
|
"Failed to get entry for pending invites component: {:?}",
|
|
|
|
err
|
|
|
|
);
|
|
|
|
// Cleanup
|
|
|
|
invites.remove(invitee);
|
|
|
|
false
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// If client comp
|
|
|
|
if let (Some(client), Some(inviter)) =
|
|
|
|
(clients.get_mut(invitee), uids.get(entity).copied())
|
|
|
|
{
|
|
|
|
if send_invite() {
|
2020-10-12 08:18:28 +00:00
|
|
|
client.send_msg(ServerGeneral::GroupInvite {
|
2020-08-07 01:59:28 +00:00
|
|
|
inviter,
|
|
|
|
timeout: PRESENTED_INVITE_TIMEOUT_DUR,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} else if agents.contains(invitee) {
|
|
|
|
send_invite();
|
2020-08-07 05:00:09 +00:00
|
|
|
} else if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-08-07 05:00:09 +00:00
|
|
|
ChatType::Meta.server_msg("Can't invite, not a player or npc".to_owned()),
|
|
|
|
);
|
2020-08-07 01:59:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Notify inviter that the invite is pending
|
|
|
|
if invite_sent {
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
2020-10-12 08:18:28 +00:00
|
|
|
client.send_msg(ServerGeneral::InvitePending(uid));
|
2020-08-07 01:59:28 +00:00
|
|
|
}
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
GroupManip::Accept => {
|
|
|
|
let mut clients = state.ecs().write_storage::<Client>();
|
|
|
|
let uids = state.ecs().read_storage::<sync::Uid>();
|
2020-08-07 01:59:28 +00:00
|
|
|
let mut invites = state.ecs().write_storage::<Invite>();
|
|
|
|
if let Some(inviter) = invites.remove(entity).and_then(|invite| {
|
|
|
|
let inviter = invite.0;
|
|
|
|
let mut pending_invites = state.ecs().write_storage::<PendingInvites>();
|
|
|
|
let pending = &mut pending_invites.get_mut(inviter)?.0;
|
|
|
|
// Check that inviter has a pending invite and remove it from the list
|
|
|
|
let invite_index = pending.iter().position(|p| p.0 == entity)?;
|
|
|
|
pending.swap_remove(invite_index);
|
|
|
|
// If no pending invites remain remove the component
|
|
|
|
if pending.is_empty() {
|
|
|
|
pending_invites.remove(inviter);
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(inviter)
|
|
|
|
}) {
|
|
|
|
if let (Some(client), Some(target)) =
|
|
|
|
(clients.get_mut(inviter), uids.get(entity).copied())
|
|
|
|
{
|
2020-10-12 08:18:28 +00:00
|
|
|
client.send_msg(ServerGeneral::InviteComplete {
|
2020-08-07 01:59:28 +00:00
|
|
|
target,
|
|
|
|
answer: InviteAnswer::Accepted,
|
|
|
|
})
|
|
|
|
}
|
2020-04-26 17:03:19 +00:00
|
|
|
let mut group_manager = state.ecs().write_resource::<GroupManager>();
|
|
|
|
group_manager.add_group_member(
|
|
|
|
inviter,
|
|
|
|
entity,
|
|
|
|
&state.ecs().entities(),
|
|
|
|
&mut state.ecs().write_storage(),
|
|
|
|
&state.ecs().read_storage(),
|
|
|
|
&uids,
|
|
|
|
|entity, group_change| {
|
|
|
|
clients
|
|
|
|
.get_mut(entity)
|
|
|
|
.and_then(|c| {
|
|
|
|
group_change
|
|
|
|
.try_map(|e| uids.get(e).copied())
|
|
|
|
.map(|g| (g, c))
|
|
|
|
})
|
2020-10-12 08:18:28 +00:00
|
|
|
.map(|(g, c)| c.send_msg(ServerGeneral::GroupUpdate(g)));
|
2020-04-26 17:03:19 +00:00
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
2020-07-19 21:49:18 +00:00
|
|
|
GroupManip::Decline => {
|
2020-04-26 17:03:19 +00:00
|
|
|
let mut clients = state.ecs().write_storage::<Client>();
|
2020-08-07 01:59:28 +00:00
|
|
|
let uids = state.ecs().read_storage::<sync::Uid>();
|
|
|
|
let mut invites = state.ecs().write_storage::<Invite>();
|
|
|
|
if let Some(inviter) = invites.remove(entity).and_then(|invite| {
|
|
|
|
let inviter = invite.0;
|
|
|
|
let mut pending_invites = state.ecs().write_storage::<PendingInvites>();
|
|
|
|
let pending = &mut pending_invites.get_mut(inviter)?.0;
|
|
|
|
// Check that inviter has a pending invite and remove it from the list
|
|
|
|
let invite_index = pending.iter().position(|p| p.0 == entity)?;
|
|
|
|
pending.swap_remove(invite_index);
|
|
|
|
// If no pending invites remain remove the component
|
|
|
|
if pending.is_empty() {
|
|
|
|
pending_invites.remove(inviter);
|
|
|
|
}
|
|
|
|
|
|
|
|
Some(inviter)
|
|
|
|
}) {
|
2020-04-26 17:03:19 +00:00
|
|
|
// Inform inviter of rejection
|
2020-08-07 01:59:28 +00:00
|
|
|
if let (Some(client), Some(target)) =
|
|
|
|
(clients.get_mut(inviter), uids.get(entity).copied())
|
|
|
|
{
|
2020-10-12 08:18:28 +00:00
|
|
|
client.send_msg(ServerGeneral::InviteComplete {
|
2020-08-07 01:59:28 +00:00
|
|
|
target,
|
|
|
|
answer: InviteAnswer::Declined,
|
|
|
|
})
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
GroupManip::Leave => {
|
|
|
|
let mut clients = state.ecs().write_storage::<Client>();
|
|
|
|
let uids = state.ecs().read_storage::<sync::Uid>();
|
|
|
|
let mut group_manager = state.ecs().write_resource::<GroupManager>();
|
2020-07-12 03:12:03 +00:00
|
|
|
group_manager.leave_group(
|
2020-04-26 17:03:19 +00:00
|
|
|
entity,
|
|
|
|
&mut state.ecs().write_storage(),
|
|
|
|
&state.ecs().read_storage(),
|
|
|
|
&uids,
|
|
|
|
&state.ecs().entities(),
|
|
|
|
&mut |entity, group_change| {
|
|
|
|
clients
|
|
|
|
.get_mut(entity)
|
|
|
|
.and_then(|c| {
|
|
|
|
group_change
|
|
|
|
.try_map(|e| uids.get(e).copied())
|
|
|
|
.map(|g| (g, c))
|
|
|
|
})
|
2020-10-12 08:18:28 +00:00
|
|
|
.map(|(g, c)| c.send_msg(ServerGeneral::GroupUpdate(g)));
|
2020-04-26 17:03:19 +00:00
|
|
|
},
|
|
|
|
);
|
|
|
|
},
|
|
|
|
GroupManip::Kick(uid) => {
|
|
|
|
let mut clients = state.ecs().write_storage::<Client>();
|
|
|
|
let uids = state.ecs().read_storage::<sync::Uid>();
|
2020-07-12 03:12:03 +00:00
|
|
|
let alignments = state.ecs().read_storage::<comp::Alignment>();
|
2020-04-26 17:03:19 +00:00
|
|
|
|
|
|
|
let target = match state.ecs().entity_from_uid(uid.into()) {
|
|
|
|
Some(t) => t,
|
|
|
|
None => {
|
|
|
|
// Inform of failure
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-07-12 00:39:50 +00:00
|
|
|
ChatType::Meta
|
2020-08-05 11:29:42 +00:00
|
|
|
.server_msg("Kick failed, target does not exist.".to_owned()),
|
2020-07-12 00:39:50 +00:00
|
|
|
);
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
|
|
|
return;
|
|
|
|
},
|
|
|
|
};
|
2020-07-12 03:12:03 +00:00
|
|
|
|
|
|
|
// Can't kick pet
|
|
|
|
if matches!(alignments.get(target), Some(comp::Alignment::Owned(owner)) if uids.get(target).map_or(true, |u| u != owner))
|
|
|
|
{
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
ChatType::Meta.server_msg("Kick failed, you can't kick pets.".to_owned()),
|
2020-07-12 03:12:03 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// Can't kick yourself
|
|
|
|
if uids.get(entity).map_or(false, |u| *u == uid) {
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
ChatType::Meta
|
|
|
|
.server_msg("Kick failed, you can't kick yourself.".to_owned()),
|
2020-07-12 03:12:03 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-04-26 17:03:19 +00:00
|
|
|
let mut groups = state.ecs().write_storage::<group::Group>();
|
|
|
|
let mut group_manager = state.ecs().write_resource::<GroupManager>();
|
|
|
|
// Make sure kicker is the group leader
|
|
|
|
match groups
|
|
|
|
.get(target)
|
|
|
|
.and_then(|group| group_manager.group_info(*group))
|
|
|
|
{
|
|
|
|
Some(info) if info.leader == entity => {
|
|
|
|
// Remove target from group
|
2020-07-12 03:12:03 +00:00
|
|
|
group_manager.leave_group(
|
2020-04-26 17:03:19 +00:00
|
|
|
target,
|
|
|
|
&mut groups,
|
|
|
|
&state.ecs().read_storage(),
|
|
|
|
&uids,
|
|
|
|
&state.ecs().entities(),
|
|
|
|
&mut |entity, group_change| {
|
|
|
|
clients
|
|
|
|
.get_mut(entity)
|
|
|
|
.and_then(|c| {
|
|
|
|
group_change
|
|
|
|
.try_map(|e| uids.get(e).copied())
|
|
|
|
.map(|g| (g, c))
|
|
|
|
})
|
2020-10-12 08:18:28 +00:00
|
|
|
.map(|(g, c)| c.send_msg(ServerGeneral::GroupUpdate(g)));
|
2020-04-26 17:03:19 +00:00
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
// Tell them the have been kicked
|
|
|
|
if let Some(client) = clients.get_mut(target) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
ChatType::Meta
|
|
|
|
.server_msg("You were removed from the group.".to_owned()),
|
2020-04-26 17:03:19 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
// Tell kicker that they were succesful
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(ChatType::Meta.server_msg("Player kicked.".to_owned()));
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
Some(_) => {
|
|
|
|
// Inform kicker that they are not the leader
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(ChatType::Meta.server_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
"Kick failed: You are not the leader of the target's group.".to_owned(),
|
2020-04-26 17:03:19 +00:00
|
|
|
));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
None => {
|
|
|
|
// Inform kicker that the target is not in a group
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-04-26 17:03:19 +00:00
|
|
|
ChatType::Meta.server_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
"Kick failed: Your target is not in a group.".to_owned(),
|
2020-04-26 17:03:19 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
GroupManip::AssignLeader(uid) => {
|
|
|
|
let mut clients = state.ecs().write_storage::<Client>();
|
|
|
|
let uids = state.ecs().read_storage::<sync::Uid>();
|
|
|
|
let target = match state.ecs().entity_from_uid(uid.into()) {
|
|
|
|
Some(t) => t,
|
|
|
|
None => {
|
|
|
|
// Inform of failure
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(ChatType::Meta.server_msg(
|
2020-04-26 17:03:19 +00:00
|
|
|
"Leadership transfer failed, target does not exist".to_owned(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
let groups = state.ecs().read_storage::<group::Group>();
|
|
|
|
let mut group_manager = state.ecs().write_resource::<GroupManager>();
|
|
|
|
// Make sure assigner is the group leader
|
|
|
|
match groups
|
|
|
|
.get(target)
|
|
|
|
.and_then(|group| group_manager.group_info(*group))
|
|
|
|
{
|
|
|
|
Some(info) if info.leader == entity => {
|
|
|
|
// Assign target as group leader
|
|
|
|
group_manager.assign_leader(
|
|
|
|
target,
|
|
|
|
&groups,
|
|
|
|
&state.ecs().entities(),
|
2020-07-19 21:49:18 +00:00
|
|
|
&state.ecs().read_storage(),
|
|
|
|
&uids,
|
2020-04-26 17:03:19 +00:00
|
|
|
|entity, group_change| {
|
|
|
|
clients
|
|
|
|
.get_mut(entity)
|
|
|
|
.and_then(|c| {
|
|
|
|
group_change
|
|
|
|
.try_map(|e| uids.get(e).copied())
|
|
|
|
.map(|g| (g, c))
|
|
|
|
})
|
2020-10-12 08:18:28 +00:00
|
|
|
.map(|(g, c)| c.send_msg(ServerGeneral::GroupUpdate(g)));
|
2020-04-26 17:03:19 +00:00
|
|
|
},
|
|
|
|
);
|
|
|
|
// Tell them they are the leader
|
|
|
|
if let Some(client) = clients.get_mut(target) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
ChatType::Meta.server_msg("You are the group leader now.".to_owned()),
|
|
|
|
);
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
|
|
|
// Tell the old leader that the transfer was succesful
|
|
|
|
if let Some(client) = clients.get_mut(target) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
ChatType::Meta
|
|
|
|
.server_msg("You are no longer the group leader.".to_owned()),
|
|
|
|
);
|
2020-04-26 17:03:19 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
Some(_) => {
|
|
|
|
// Inform transferer that they are not the leader
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(
|
2020-04-26 17:03:19 +00:00
|
|
|
ChatType::Meta.server_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
"Transfer failed: You are not the leader of the target's group."
|
2020-04-26 17:03:19 +00:00
|
|
|
.to_owned(),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
None => {
|
|
|
|
// Inform transferer that the target is not in a group
|
|
|
|
if let Some(client) = clients.get_mut(entity) {
|
Redo Network Frontend.
Rather than having a single Stream to handle ALL data, seperate into multiple streams:
- Ping Stream, for seperate PINGS
- Register Stream, only used till the client is registered, then no longer used!
- General Stream, used for msg that can occur always
- NotInGame Stream, used for everything NOT ingame, e.g. Character Screen
- InGame Stream, used for all GAME data, players, terrain, entities, etc...
This version does compile, and gets the client registered (with auth too) but doesnt get to the char screen yet.
This fixes also the ignoring messages problem we had, as we are not sending data to the register stream!
This fixes also the problem that the server had to sleep for the Stream Creation, as the Server is now creating the streams and client has to sleep.
2020-10-04 18:20:18 +00:00
|
|
|
client.send_msg(ChatType::Meta.server_msg(
|
2020-08-05 11:29:42 +00:00
|
|
|
"Transfer failed: Your target is not in a group.".to_owned(),
|
2020-04-26 17:03:19 +00:00
|
|
|
));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|