mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
pack together InGame, CharacterScreen and General variant in a single enum, as requested by zesterer.
His reason to reqeust that is, that there might not be a perfect disctinction in the future. Now we need to send ServerGeneral over streams and do additional checking at various places to verify that not the wrong variant is send.
This commit is contained in:
parent
55b59fbe07
commit
2a7378b4ae
@ -25,10 +25,9 @@ use common::{
|
|||||||
},
|
},
|
||||||
event::{EventBus, LocalEvent},
|
event::{EventBus, LocalEvent},
|
||||||
msg::{
|
msg::{
|
||||||
validate_chat_msg, ChatMsgValidationError, ClientCharacterScreen, ClientGeneral,
|
validate_chat_msg, ChatMsgValidationError, ClientGeneral, ClientInGame, ClientMsg,
|
||||||
ClientInGame, ClientIngame, ClientMsg, ClientRegister, ClientType, DisconnectReason,
|
ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification, PingMsg,
|
||||||
InviteAnswer, Notification, PingMsg, PlayerInfo, PlayerListUpdate, RegisterError,
|
PlayerInfo, PlayerListUpdate, RegisterError, ServerGeneral, ServerInfo, ServerInit,
|
||||||
ServerCharacterScreen, ServerGeneral, ServerInGame, ServerInfo, ServerInit,
|
|
||||||
ServerRegisterAnswer, MAX_BYTES_CHAT_MSG,
|
ServerRegisterAnswer, MAX_BYTES_CHAT_MSG,
|
||||||
},
|
},
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
@ -71,7 +70,7 @@ pub enum Event {
|
|||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
registered: bool,
|
registered: bool,
|
||||||
in_game: Option<ClientIngame>,
|
in_game: Option<ClientInGame>,
|
||||||
thread_pool: ThreadPool,
|
thread_pool: ThreadPool,
|
||||||
pub server_info: ServerInfo,
|
pub server_info: ServerInfo,
|
||||||
/// Just the "base" layer for LOD; currently includes colors and nothing
|
/// Just the "base" layer for LOD; currently includes colors and nothing
|
||||||
@ -466,39 +465,46 @@ impl Client {
|
|||||||
let msg: ClientMsg = msg.into();
|
let msg: ClientMsg = msg.into();
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
{
|
{
|
||||||
// These assertions verify that the state is correct when a message is sent!
|
const C_TYPE: ClientType = ClientType::Game;
|
||||||
match &msg {
|
let verified = msg.verify(C_TYPE, self.registered, self.in_game);
|
||||||
ClientMsg::Type(_) | ClientMsg::Register(_) => assert!(
|
assert!(
|
||||||
!self.registered,
|
verified,
|
||||||
"must not send msg when already registered"
|
format!(
|
||||||
),
|
"c_type: {:?}, registered: {}, in_game: {:?}, msg: {:?}",
|
||||||
ClientMsg::CharacterScreen(_) => {
|
C_TYPE, self.registered, self.in_game, msg
|
||||||
assert!(
|
)
|
||||||
self.registered,
|
);
|
||||||
"must not send character_screen msg when not registered"
|
|
||||||
);
|
|
||||||
assert!(
|
|
||||||
self.in_game.is_none(),
|
|
||||||
"must not send character_screen msg when not in character screen"
|
|
||||||
);
|
|
||||||
},
|
|
||||||
ClientMsg::InGame(_) => assert!(
|
|
||||||
self.in_game.is_some(),
|
|
||||||
"must not send in_game msg when not in game"
|
|
||||||
),
|
|
||||||
ClientMsg::General(_) => assert!(
|
|
||||||
self.registered,
|
|
||||||
"must not send general msg when not registered"
|
|
||||||
),
|
|
||||||
ClientMsg::Ping(_) => (),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
match msg {
|
match msg {
|
||||||
ClientMsg::Type(msg) => self.register_stream.send(msg),
|
ClientMsg::Type(msg) => self.register_stream.send(msg),
|
||||||
ClientMsg::Register(msg) => self.register_stream.send(msg),
|
ClientMsg::Register(msg) => self.register_stream.send(msg),
|
||||||
ClientMsg::CharacterScreen(msg) => self.character_screen_stream.send(msg),
|
ClientMsg::General(msg) => {
|
||||||
ClientMsg::InGame(msg) => self.in_game_stream.send(msg),
|
let stream = match msg {
|
||||||
ClientMsg::General(msg) => self.general_stream.send(msg),
|
ClientGeneral::RequestCharacterList
|
||||||
|
| ClientGeneral::CreateCharacter { .. }
|
||||||
|
| ClientGeneral::DeleteCharacter(_)
|
||||||
|
| ClientGeneral::Character(_)
|
||||||
|
| ClientGeneral::Spectate => &mut self.character_screen_stream,
|
||||||
|
//Only in game
|
||||||
|
ClientGeneral::ControllerInputs(_)
|
||||||
|
| ClientGeneral::ControlEvent(_)
|
||||||
|
| ClientGeneral::ControlAction(_)
|
||||||
|
| ClientGeneral::SetViewDistance(_)
|
||||||
|
| ClientGeneral::BreakBlock(_)
|
||||||
|
| ClientGeneral::PlaceBlock(_, _)
|
||||||
|
| ClientGeneral::ExitInGame
|
||||||
|
| ClientGeneral::PlayerPhysics { .. }
|
||||||
|
| ClientGeneral::TerrainChunkRequest { .. }
|
||||||
|
| ClientGeneral::UnlockSkill(_)
|
||||||
|
| ClientGeneral::RefundSkill(_)
|
||||||
|
| ClientGeneral::UnlockSkillGroup(_) => &mut self.in_game_stream,
|
||||||
|
//Always possible
|
||||||
|
ClientGeneral::ChatMsg(_)
|
||||||
|
| ClientGeneral::Disconnect
|
||||||
|
| ClientGeneral::Terminate => &mut self.general_stream,
|
||||||
|
};
|
||||||
|
stream.send(msg)
|
||||||
|
},
|
||||||
ClientMsg::Ping(msg) => self.ping_stream.send(msg),
|
ClientMsg::Ping(msg) => self.ping_stream.send(msg),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,10 +524,10 @@ impl Client {
|
|||||||
|
|
||||||
/// Request a state transition to `ClientState::Character`.
|
/// Request a state transition to `ClientState::Character`.
|
||||||
pub fn request_character(&mut self, character_id: CharacterId) {
|
pub fn request_character(&mut self, character_id: CharacterId) {
|
||||||
self.send_msg(ClientCharacterScreen::Character(character_id));
|
self.send_msg(ClientGeneral::Character(character_id));
|
||||||
|
|
||||||
//Assume we are in_game unless server tells us otherwise
|
//Assume we are in_game unless server tells us otherwise
|
||||||
self.in_game = Some(ClientIngame::Character);
|
self.in_game = Some(ClientInGame::Character);
|
||||||
|
|
||||||
self.active_character_id = Some(character_id);
|
self.active_character_id = Some(character_id);
|
||||||
}
|
}
|
||||||
@ -529,19 +535,19 @@ impl Client {
|
|||||||
/// Load the current players character list
|
/// Load the current players character list
|
||||||
pub fn load_character_list(&mut self) {
|
pub fn load_character_list(&mut self) {
|
||||||
self.character_list.loading = true;
|
self.character_list.loading = true;
|
||||||
self.send_msg(ClientCharacterScreen::RequestCharacterList);
|
self.send_msg(ClientGeneral::RequestCharacterList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// New character creation
|
/// New character creation
|
||||||
pub fn create_character(&mut self, alias: String, tool: Option<String>, body: comp::Body) {
|
pub fn create_character(&mut self, alias: String, tool: Option<String>, body: comp::Body) {
|
||||||
self.character_list.loading = true;
|
self.character_list.loading = true;
|
||||||
self.send_msg(ClientCharacterScreen::CreateCharacter { alias, tool, body });
|
self.send_msg(ClientGeneral::CreateCharacter { alias, tool, body });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Character deletion
|
/// Character deletion
|
||||||
pub fn delete_character(&mut self, character_id: CharacterId) {
|
pub fn delete_character(&mut self, character_id: CharacterId) {
|
||||||
self.character_list.loading = true;
|
self.character_list.loading = true;
|
||||||
self.send_msg(ClientCharacterScreen::DeleteCharacter(character_id));
|
self.send_msg(ClientGeneral::DeleteCharacter(character_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send disconnect message to the server
|
/// Send disconnect message to the server
|
||||||
@ -552,34 +558,34 @@ impl Client {
|
|||||||
|
|
||||||
/// Request a state transition to `ClientState::Registered` from an ingame
|
/// Request a state transition to `ClientState::Registered` from an ingame
|
||||||
/// state.
|
/// state.
|
||||||
pub fn request_remove_character(&mut self) { self.send_msg(ClientInGame::ExitInGame); }
|
pub fn request_remove_character(&mut self) { self.send_msg(ClientGeneral::ExitInGame); }
|
||||||
|
|
||||||
pub fn set_view_distance(&mut self, view_distance: u32) {
|
pub fn set_view_distance(&mut self, view_distance: u32) {
|
||||||
self.view_distance = Some(view_distance.max(1).min(65));
|
self.view_distance = Some(view_distance.max(1).min(65));
|
||||||
self.send_msg(ClientInGame::SetViewDistance(self.view_distance.unwrap()));
|
self.send_msg(ClientGeneral::SetViewDistance(self.view_distance.unwrap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_slot(&mut self, slot: comp::slot::Slot) {
|
pub fn use_slot(&mut self, slot: comp::slot::Slot) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::InventoryManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::InventoryManip(
|
||||||
InventoryManip::Use(slot),
|
InventoryManip::Use(slot),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn swap_slots(&mut self, a: comp::slot::Slot, b: comp::slot::Slot) {
|
pub fn swap_slots(&mut self, a: comp::slot::Slot, b: comp::slot::Slot) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::InventoryManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::InventoryManip(
|
||||||
InventoryManip::Swap(a, b),
|
InventoryManip::Swap(a, b),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn drop_slot(&mut self, slot: comp::slot::Slot) {
|
pub fn drop_slot(&mut self, slot: comp::slot::Slot) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::InventoryManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::InventoryManip(
|
||||||
InventoryManip::Drop(slot),
|
InventoryManip::Drop(slot),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pick_up(&mut self, entity: EcsEntity) {
|
pub fn pick_up(&mut self, entity: EcsEntity) {
|
||||||
if let Some(uid) = self.state.read_component_copied(entity) {
|
if let Some(uid) = self.state.read_component_copied(entity) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::InventoryManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::InventoryManip(
|
||||||
InventoryManip::Pickup(uid),
|
InventoryManip::Pickup(uid),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@ -599,7 +605,7 @@ impl Client {
|
|||||||
|
|
||||||
pub fn craft_recipe(&mut self, recipe: &str) -> bool {
|
pub fn craft_recipe(&mut self, recipe: &str) -> bool {
|
||||||
if self.can_craft_recipe(recipe) {
|
if self.can_craft_recipe(recipe) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::InventoryManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::InventoryManip(
|
||||||
InventoryManip::CraftRecipe(recipe.to_string()),
|
InventoryManip::CraftRecipe(recipe.to_string()),
|
||||||
)));
|
)));
|
||||||
true
|
true
|
||||||
@ -618,11 +624,11 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable_lantern(&mut self) {
|
pub fn enable_lantern(&mut self) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::EnableLantern));
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::EnableLantern));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable_lantern(&mut self) {
|
pub fn disable_lantern(&mut self) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::DisableLantern));
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::DisableLantern));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn max_group_size(&self) -> u32 { self.max_group_size }
|
pub fn max_group_size(&self) -> u32 { self.max_group_size }
|
||||||
@ -640,7 +646,7 @@ impl Client {
|
|||||||
pub fn pending_invites(&self) -> &HashSet<Uid> { &self.pending_invites }
|
pub fn pending_invites(&self) -> &HashSet<Uid> { &self.pending_invites }
|
||||||
|
|
||||||
pub fn send_group_invite(&mut self, invitee: Uid) {
|
pub fn send_group_invite(&mut self, invitee: Uid) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::GroupManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::GroupManip(
|
||||||
GroupManip::Invite(invitee),
|
GroupManip::Invite(invitee),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
@ -648,7 +654,7 @@ impl Client {
|
|||||||
pub fn accept_group_invite(&mut self) {
|
pub fn accept_group_invite(&mut self) {
|
||||||
// Clear invite
|
// Clear invite
|
||||||
self.group_invite.take();
|
self.group_invite.take();
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::GroupManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::GroupManip(
|
||||||
GroupManip::Accept,
|
GroupManip::Accept,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@ -656,25 +662,25 @@ impl Client {
|
|||||||
pub fn decline_group_invite(&mut self) {
|
pub fn decline_group_invite(&mut self) {
|
||||||
// Clear invite
|
// Clear invite
|
||||||
self.group_invite.take();
|
self.group_invite.take();
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::GroupManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::GroupManip(
|
||||||
GroupManip::Decline,
|
GroupManip::Decline,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn leave_group(&mut self) {
|
pub fn leave_group(&mut self) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::GroupManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::GroupManip(
|
||||||
GroupManip::Leave,
|
GroupManip::Leave,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kick_from_group(&mut self, uid: Uid) {
|
pub fn kick_from_group(&mut self, uid: Uid) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::GroupManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::GroupManip(
|
||||||
GroupManip::Kick(uid),
|
GroupManip::Kick(uid),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_group_leader(&mut self, uid: Uid) {
|
pub fn assign_group_leader(&mut self, uid: Uid) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::GroupManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::GroupManip(
|
||||||
GroupManip::AssignLeader(uid),
|
GroupManip::AssignLeader(uid),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@ -697,11 +703,11 @@ impl Client {
|
|||||||
|
|
||||||
pub fn mount(&mut self, entity: EcsEntity) {
|
pub fn mount(&mut self, entity: EcsEntity) {
|
||||||
if let Some(uid) = self.state.read_component_copied(entity) {
|
if let Some(uid) = self.state.read_component_copied(entity) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::Mount(uid)));
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::Mount(uid)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unmount(&mut self) { self.send_msg(ClientInGame::ControlEvent(ControlEvent::Unmount)); }
|
pub fn unmount(&mut self) { self.send_msg(ClientGeneral::ControlEvent(ControlEvent::Unmount)); }
|
||||||
|
|
||||||
pub fn respawn(&mut self) {
|
pub fn respawn(&mut self) {
|
||||||
if self
|
if self
|
||||||
@ -711,7 +717,7 @@ impl Client {
|
|||||||
.get(self.entity)
|
.get(self.entity)
|
||||||
.map_or(false, |s| s.is_dead)
|
.map_or(false, |s| s.is_dead)
|
||||||
{
|
{
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::Respawn));
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::Respawn));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,7 +814,7 @@ impl Client {
|
|||||||
{
|
{
|
||||||
controller.actions.push(control_action);
|
controller.actions.push(control_action);
|
||||||
}
|
}
|
||||||
self.send_msg(ClientInGame::ControlAction(control_action));
|
self.send_msg(ClientGeneral::ControlAction(control_action));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view_distance(&self) -> Option<u32> { self.view_distance }
|
pub fn view_distance(&self) -> Option<u32> { self.view_distance }
|
||||||
@ -852,13 +858,15 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn place_block(&mut self, pos: Vec3<i32>, block: Block) {
|
pub fn place_block(&mut self, pos: Vec3<i32>, block: Block) {
|
||||||
self.send_msg(ClientInGame::PlaceBlock(pos, block));
|
self.send_msg(ClientGeneral::PlaceBlock(pos, block));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_block(&mut self, pos: Vec3<i32>) { self.send_msg(ClientInGame::BreakBlock(pos)); }
|
pub fn remove_block(&mut self, pos: Vec3<i32>) {
|
||||||
|
self.send_msg(ClientGeneral::BreakBlock(pos));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn collect_block(&mut self, pos: Vec3<i32>) {
|
pub fn collect_block(&mut self, pos: Vec3<i32>) {
|
||||||
self.send_msg(ClientInGame::ControlEvent(ControlEvent::InventoryManip(
|
self.send_msg(ClientGeneral::ControlEvent(ControlEvent::InventoryManip(
|
||||||
InventoryManip::Collect(pos),
|
InventoryManip::Collect(pos),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
@ -915,7 +923,7 @@ impl Client {
|
|||||||
"Couldn't access controller component on client entity"
|
"Couldn't access controller component on client entity"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.send_msg_err(ClientInGame::ControllerInputs(inputs))?;
|
self.send_msg_err(ClientGeneral::ControllerInputs(inputs))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2) Build up a list of events for this frame, to be passed to the frontend.
|
// 2) Build up a list of events for this frame, to be passed to the frontend.
|
||||||
@ -1019,7 +1027,7 @@ impl Client {
|
|||||||
if self.state.terrain().get_key(*key).is_none() {
|
if self.state.terrain().get_key(*key).is_none() {
|
||||||
if !skip_mode && !self.pending_chunks.contains_key(key) {
|
if !skip_mode && !self.pending_chunks.contains_key(key) {
|
||||||
if self.pending_chunks.len() < 4 {
|
if self.pending_chunks.len() < 4 {
|
||||||
self.send_msg_err(ClientInGame::TerrainChunkRequest {
|
self.send_msg_err(ClientGeneral::TerrainChunkRequest {
|
||||||
key: *key,
|
key: *key,
|
||||||
})?;
|
})?;
|
||||||
self.pending_chunks.insert(*key, Instant::now());
|
self.pending_chunks.insert(*key, Instant::now());
|
||||||
@ -1065,7 +1073,7 @@ impl Client {
|
|||||||
self.state.read_storage().get(self.entity).cloned(),
|
self.state.read_storage().get(self.entity).cloned(),
|
||||||
) {
|
) {
|
||||||
self.in_game_stream
|
self.in_game_stream
|
||||||
.send(ClientInGame::PlayerPhysics { pos, vel, ori })?;
|
.send(ClientGeneral::PlayerPhysics { pos, vel, ori })?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1237,6 +1245,7 @@ impl Client {
|
|||||||
ServerGeneral::Notification(n) => {
|
ServerGeneral::Notification(n) => {
|
||||||
frontend_events.push(Event::Notification(n));
|
frontend_events.push(Event::Notification(n));
|
||||||
},
|
},
|
||||||
|
_ => unreachable!("Not a general msg"),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1244,10 +1253,10 @@ impl Client {
|
|||||||
fn handle_server_in_game_msg(
|
fn handle_server_in_game_msg(
|
||||||
&mut self,
|
&mut self,
|
||||||
frontend_events: &mut Vec<Event>,
|
frontend_events: &mut Vec<Event>,
|
||||||
msg: ServerInGame,
|
msg: ServerGeneral,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
match msg {
|
match msg {
|
||||||
ServerInGame::GroupUpdate(change_notification) => {
|
ServerGeneral::GroupUpdate(change_notification) => {
|
||||||
use comp::group::ChangeNotification::*;
|
use comp::group::ChangeNotification::*;
|
||||||
// Note: we use a hashmap since this would not work with entities outside
|
// Note: we use a hashmap since this would not work with entities outside
|
||||||
// the view distance
|
// the view distance
|
||||||
@ -1319,15 +1328,15 @@ impl Client {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ServerInGame::GroupInvite { inviter, timeout } => {
|
ServerGeneral::GroupInvite { inviter, timeout } => {
|
||||||
self.group_invite = Some((inviter, std::time::Instant::now(), timeout));
|
self.group_invite = Some((inviter, std::time::Instant::now(), timeout));
|
||||||
},
|
},
|
||||||
ServerInGame::InvitePending(uid) => {
|
ServerGeneral::InvitePending(uid) => {
|
||||||
if !self.pending_invites.insert(uid) {
|
if !self.pending_invites.insert(uid) {
|
||||||
warn!("Received message about pending invite that was already pending");
|
warn!("Received message about pending invite that was already pending");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ServerInGame::InviteComplete { target, answer } => {
|
ServerGeneral::InviteComplete { target, answer } => {
|
||||||
if !self.pending_invites.remove(&target) {
|
if !self.pending_invites.remove(&target) {
|
||||||
warn!(
|
warn!(
|
||||||
"Received completed invite message for invite that was not in the list of \
|
"Received completed invite message for invite that was not in the list of \
|
||||||
@ -1345,11 +1354,11 @@ impl Client {
|
|||||||
frontend_events.push(Event::Chat(comp::ChatType::Meta.chat_msg(msg)));
|
frontend_events.push(Event::Chat(comp::ChatType::Meta.chat_msg(msg)));
|
||||||
},
|
},
|
||||||
// Cleanup for when the client goes back to the `in_game = None`
|
// Cleanup for when the client goes back to the `in_game = None`
|
||||||
ServerInGame::ExitInGameSuccess => {
|
ServerGeneral::ExitInGameSuccess => {
|
||||||
self.in_game = None;
|
self.in_game = None;
|
||||||
self.clean_state();
|
self.clean_state();
|
||||||
},
|
},
|
||||||
ServerInGame::InventoryUpdate(mut inventory, event) => {
|
ServerGeneral::InventoryUpdate(mut inventory, event) => {
|
||||||
match event {
|
match event {
|
||||||
InventoryUpdateEvent::CollectFailed => {},
|
InventoryUpdateEvent::CollectFailed => {},
|
||||||
_ => {
|
_ => {
|
||||||
@ -1363,25 +1372,25 @@ impl Client {
|
|||||||
|
|
||||||
frontend_events.push(Event::InventoryUpdated(event));
|
frontend_events.push(Event::InventoryUpdated(event));
|
||||||
},
|
},
|
||||||
ServerInGame::TerrainChunkUpdate { key, chunk } => {
|
ServerGeneral::TerrainChunkUpdate { key, chunk } => {
|
||||||
if let Ok(chunk) = chunk {
|
if let Ok(chunk) = chunk {
|
||||||
self.state.insert_chunk(key, *chunk);
|
self.state.insert_chunk(key, *chunk);
|
||||||
}
|
}
|
||||||
self.pending_chunks.remove(&key);
|
self.pending_chunks.remove(&key);
|
||||||
},
|
},
|
||||||
ServerInGame::TerrainBlockUpdates(mut blocks) => {
|
ServerGeneral::TerrainBlockUpdates(mut blocks) => {
|
||||||
blocks.drain().for_each(|(pos, block)| {
|
blocks.drain().for_each(|(pos, block)| {
|
||||||
self.state.set_block(pos, block);
|
self.state.set_block(pos, block);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
ServerInGame::SetViewDistance(vd) => {
|
ServerGeneral::SetViewDistance(vd) => {
|
||||||
self.view_distance = Some(vd);
|
self.view_distance = Some(vd);
|
||||||
frontend_events.push(Event::SetViewDistance(vd));
|
frontend_events.push(Event::SetViewDistance(vd));
|
||||||
},
|
},
|
||||||
ServerInGame::Outcomes(outcomes) => {
|
ServerGeneral::Outcomes(outcomes) => {
|
||||||
frontend_events.extend(outcomes.into_iter().map(Event::Outcome))
|
frontend_events.extend(outcomes.into_iter().map(Event::Outcome))
|
||||||
},
|
},
|
||||||
ServerInGame::Knockback(impulse) => {
|
ServerGeneral::Knockback(impulse) => {
|
||||||
self.state
|
self.state
|
||||||
.ecs()
|
.ecs()
|
||||||
.read_resource::<EventBus<LocalEvent>>()
|
.read_resource::<EventBus<LocalEvent>>()
|
||||||
@ -1390,35 +1399,34 @@ impl Client {
|
|||||||
impulse,
|
impulse,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
_ => unreachable!("Not a in_game message"),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_server_character_screen_msg(
|
fn handle_server_character_screen_msg(&mut self, msg: ServerGeneral) -> Result<(), Error> {
|
||||||
&mut self,
|
|
||||||
msg: ServerCharacterScreen,
|
|
||||||
) -> Result<(), Error> {
|
|
||||||
match msg {
|
match msg {
|
||||||
ServerCharacterScreen::CharacterListUpdate(character_list) => {
|
ServerGeneral::CharacterListUpdate(character_list) => {
|
||||||
self.character_list.characters = character_list;
|
self.character_list.characters = character_list;
|
||||||
self.character_list.loading = false;
|
self.character_list.loading = false;
|
||||||
},
|
},
|
||||||
ServerCharacterScreen::CharacterActionError(error) => {
|
ServerGeneral::CharacterActionError(error) => {
|
||||||
warn!("CharacterActionError: {:?}.", error);
|
warn!("CharacterActionError: {:?}.", error);
|
||||||
self.character_list.error = Some(error);
|
self.character_list.error = Some(error);
|
||||||
},
|
},
|
||||||
ServerCharacterScreen::CharacterDataLoadError(error) => {
|
ServerGeneral::CharacterDataLoadError(error) => {
|
||||||
trace!("Handling join error by server");
|
trace!("Handling join error by server");
|
||||||
self.in_game = None;
|
self.in_game = None;
|
||||||
self.clean_state();
|
self.clean_state();
|
||||||
self.character_list.error = Some(error);
|
self.character_list.error = Some(error);
|
||||||
},
|
},
|
||||||
ServerCharacterScreen::CharacterSuccess => {
|
ServerGeneral::CharacterSuccess => {
|
||||||
debug!("client is now in ingame state on server");
|
debug!("client is now in ingame state on server");
|
||||||
if let Some(vd) = self.view_distance {
|
if let Some(vd) = self.view_distance {
|
||||||
self.set_view_distance(vd);
|
self.set_view_distance(vd);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
_ => unreachable!("Not a character_screen msg"),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1518,7 +1526,7 @@ impl Client {
|
|||||||
|
|
||||||
pub fn uid(&self) -> Option<Uid> { self.state.read_component_copied(self.entity) }
|
pub fn uid(&self) -> Option<Uid> { self.state.read_component_copied(self.entity) }
|
||||||
|
|
||||||
pub fn in_game(&self) -> Option<ClientIngame> { self.in_game }
|
pub fn in_game(&self) -> Option<ClientInGame> { self.in_game }
|
||||||
|
|
||||||
pub fn registered(&self) -> bool { self.registered }
|
pub fn registered(&self) -> bool { self.registered }
|
||||||
|
|
||||||
|
@ -12,16 +12,13 @@ use vek::*;
|
|||||||
/// streams though). It's used to verify the correctness of the state in
|
/// streams though). It's used to verify the correctness of the state in
|
||||||
/// debug_assertions
|
/// debug_assertions
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
#[allow(clippy::clippy::large_enum_variant)]
|
||||||
pub enum ClientMsg {
|
pub enum ClientMsg {
|
||||||
///Send on the first connection ONCE to identify client intention for
|
///Send on the first connection ONCE to identify client intention for
|
||||||
/// server
|
/// server
|
||||||
Type(ClientType),
|
Type(ClientType),
|
||||||
///Send ONCE to register/auth to the server
|
///Send ONCE to register/auth to the server
|
||||||
Register(ClientRegister),
|
Register(ClientRegister),
|
||||||
///Msg only to send while in character screen, e.g. `CreateCharacter`
|
|
||||||
CharacterScreen(ClientCharacterScreen),
|
|
||||||
///Msg only to send while playing in game, e.g. `PlayerPositionUpdates`
|
|
||||||
InGame(ClientInGame),
|
|
||||||
///Msg that can be send ALWAYS as soon as we are registered, e.g. `Chat`
|
///Msg that can be send ALWAYS as soon as we are registered, e.g. `Chat`
|
||||||
General(ClientGeneral),
|
General(ClientGeneral),
|
||||||
Ping(PingMsg),
|
Ping(PingMsg),
|
||||||
@ -47,9 +44,10 @@ pub struct ClientRegister {
|
|||||||
pub token_or_username: String,
|
pub token_or_username: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
//messages send by clients only valid when in character screen
|
/// Messages sent from the client to the server
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum ClientCharacterScreen {
|
pub enum ClientGeneral {
|
||||||
|
//Only in Character Screen
|
||||||
RequestCharacterList,
|
RequestCharacterList,
|
||||||
CreateCharacter {
|
CreateCharacter {
|
||||||
alias: String,
|
alias: String,
|
||||||
@ -59,11 +57,7 @@ pub enum ClientCharacterScreen {
|
|||||||
DeleteCharacter(CharacterId),
|
DeleteCharacter(CharacterId),
|
||||||
Character(CharacterId),
|
Character(CharacterId),
|
||||||
Spectate,
|
Spectate,
|
||||||
}
|
//Only in game
|
||||||
|
|
||||||
//messages send by clients only valid when in game (with a character)
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub enum ClientInGame {
|
|
||||||
ControllerInputs(comp::ControllerInputs),
|
ControllerInputs(comp::ControllerInputs),
|
||||||
ControlEvent(comp::ControlEvent),
|
ControlEvent(comp::ControlEvent),
|
||||||
ControlAction(comp::ControlAction),
|
ControlAction(comp::ControlAction),
|
||||||
@ -82,16 +76,59 @@ pub enum ClientInGame {
|
|||||||
UnlockSkill(Skill),
|
UnlockSkill(Skill),
|
||||||
RefundSkill(Skill),
|
RefundSkill(Skill),
|
||||||
UnlockSkillGroup(SkillGroupType),
|
UnlockSkillGroup(SkillGroupType),
|
||||||
}
|
//Always possible
|
||||||
|
|
||||||
/// Messages sent from the client to the server
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub enum ClientGeneral {
|
|
||||||
ChatMsg(String),
|
ChatMsg(String),
|
||||||
Disconnect,
|
Disconnect,
|
||||||
Terminate,
|
Terminate,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ClientMsg {
|
||||||
|
pub fn verify(
|
||||||
|
&self,
|
||||||
|
c_type: ClientType,
|
||||||
|
registered: bool,
|
||||||
|
in_game: Option<super::ClientInGame>,
|
||||||
|
) -> bool {
|
||||||
|
match self {
|
||||||
|
ClientMsg::Type(t) => c_type == *t,
|
||||||
|
ClientMsg::Register(_) => !registered && in_game.is_none(),
|
||||||
|
ClientMsg::General(g) => {
|
||||||
|
registered
|
||||||
|
&& match g {
|
||||||
|
ClientGeneral::RequestCharacterList
|
||||||
|
| ClientGeneral::CreateCharacter { .. }
|
||||||
|
| ClientGeneral::DeleteCharacter(_) => {
|
||||||
|
c_type != ClientType::ChatOnly && in_game.is_none()
|
||||||
|
},
|
||||||
|
ClientGeneral::Character(_) | ClientGeneral::Spectate => {
|
||||||
|
c_type == ClientType::Game && in_game.is_none()
|
||||||
|
},
|
||||||
|
//Only in game
|
||||||
|
ClientGeneral::ControllerInputs(_)
|
||||||
|
| ClientGeneral::ControlEvent(_)
|
||||||
|
| ClientGeneral::ControlAction(_)
|
||||||
|
| ClientGeneral::SetViewDistance(_)
|
||||||
|
| ClientGeneral::BreakBlock(_)
|
||||||
|
| ClientGeneral::PlaceBlock(_, _)
|
||||||
|
| ClientGeneral::ExitInGame
|
||||||
|
| ClientGeneral::PlayerPhysics { .. }
|
||||||
|
| ClientGeneral::TerrainChunkRequest { .. }
|
||||||
|
| ClientGeneral::UnlockSkill(_)
|
||||||
|
| ClientGeneral::RefundSkill(_)
|
||||||
|
| ClientGeneral::UnlockSkillGroup(_) => {
|
||||||
|
c_type == ClientType::Game && in_game.is_some()
|
||||||
|
},
|
||||||
|
//Always possible
|
||||||
|
ClientGeneral::ChatMsg(_)
|
||||||
|
| ClientGeneral::Disconnect
|
||||||
|
| ClientGeneral::Terminate => true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ClientMsg::Ping(_) => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
end of 2nd level Enums
|
end of 2nd level Enums
|
||||||
*/
|
*/
|
||||||
@ -104,14 +141,6 @@ impl Into<ClientMsg> for ClientRegister {
|
|||||||
fn into(self) -> ClientMsg { ClientMsg::Register(self) }
|
fn into(self) -> ClientMsg { ClientMsg::Register(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<ClientMsg> for ClientCharacterScreen {
|
|
||||||
fn into(self) -> ClientMsg { ClientMsg::CharacterScreen(self) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<ClientMsg> for ClientInGame {
|
|
||||||
fn into(self) -> ClientMsg { ClientMsg::InGame(self) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<ClientMsg> for ClientGeneral {
|
impl Into<ClientMsg> for ClientGeneral {
|
||||||
fn into(self) -> ClientMsg { ClientMsg::General(self) }
|
fn into(self) -> ClientMsg { ClientMsg::General(self) }
|
||||||
}
|
}
|
||||||
|
@ -5,21 +5,18 @@ pub mod world_packet;
|
|||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use self::{
|
pub use self::{
|
||||||
client::{
|
client::{ClientGeneral, ClientMsg, ClientRegister, ClientType},
|
||||||
ClientCharacterScreen, ClientGeneral, ClientInGame, ClientMsg, ClientRegister, ClientType,
|
|
||||||
},
|
|
||||||
ecs_packet::EcsCompPacket,
|
ecs_packet::EcsCompPacket,
|
||||||
server::{
|
server::{
|
||||||
CharacterInfo, DisconnectReason, InviteAnswer, Notification, PlayerInfo, PlayerListUpdate,
|
CharacterInfo, DisconnectReason, InviteAnswer, Notification, PlayerInfo, PlayerListUpdate,
|
||||||
RegisterError, ServerCharacterScreen, ServerGeneral, ServerInGame, ServerInfo, ServerInit,
|
RegisterError, ServerGeneral, ServerInfo, ServerInit, ServerMsg, ServerRegisterAnswer,
|
||||||
ServerMsg, ServerRegisterAnswer,
|
|
||||||
},
|
},
|
||||||
world_packet::WorldMapMsg,
|
world_packet::WorldMapMsg,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
|
||||||
pub enum ClientIngame {
|
pub enum ClientInGame {
|
||||||
Spectator,
|
Spectator,
|
||||||
Character,
|
Character,
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use super::{EcsCompPacket, PingMsg};
|
use super::{ClientType, EcsCompPacket, PingMsg};
|
||||||
use crate::{
|
use crate::{
|
||||||
character::CharacterItem,
|
character::CharacterItem,
|
||||||
comp,
|
comp,
|
||||||
@ -24,12 +24,6 @@ pub enum ServerMsg {
|
|||||||
Init(ServerInit),
|
Init(ServerInit),
|
||||||
/// Result to `ClientMsg::Register`. send ONCE
|
/// Result to `ClientMsg::Register`. send ONCE
|
||||||
RegisterAnswer(ServerRegisterAnswer),
|
RegisterAnswer(ServerRegisterAnswer),
|
||||||
/// Msg only to send when client is on the character screen, e.g.
|
|
||||||
/// `CharacterListUpdate`
|
|
||||||
CharacterScreen(ServerCharacterScreen),
|
|
||||||
/// Msg only to send when client is playing in game, e.g.
|
|
||||||
/// `TerrainChunkUpdate`
|
|
||||||
InGame(ServerInGame),
|
|
||||||
///Msg that can be send ALWAYS as soon as client is registered, e.g. `Chat`
|
///Msg that can be send ALWAYS as soon as client is registered, e.g. `Chat`
|
||||||
General(ServerGeneral),
|
General(ServerGeneral),
|
||||||
Ping(PingMsg),
|
Ping(PingMsg),
|
||||||
@ -65,9 +59,10 @@ pub enum ServerInit {
|
|||||||
|
|
||||||
pub type ServerRegisterAnswer = Result<(), RegisterError>;
|
pub type ServerRegisterAnswer = Result<(), RegisterError>;
|
||||||
|
|
||||||
//Messages only allowed while client in character screen
|
/// Messages sent from the server to the client
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum ServerCharacterScreen {
|
pub enum ServerGeneral {
|
||||||
|
//Character Screen related
|
||||||
/// An error occurred while loading character data
|
/// An error occurred while loading character data
|
||||||
CharacterDataLoadError(String),
|
CharacterDataLoadError(String),
|
||||||
/// A list of characters belonging to the a authenticated player was sent
|
/// A list of characters belonging to the a authenticated player was sent
|
||||||
@ -75,23 +70,21 @@ pub enum ServerCharacterScreen {
|
|||||||
/// An error occurred while creating or deleting a character
|
/// An error occurred while creating or deleting a character
|
||||||
CharacterActionError(String),
|
CharacterActionError(String),
|
||||||
CharacterSuccess,
|
CharacterSuccess,
|
||||||
}
|
//Ingame related
|
||||||
|
|
||||||
//Messages only allowed while client is in game (with a character)
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub enum ServerInGame {
|
|
||||||
GroupUpdate(comp::group::ChangeNotification<sync::Uid>),
|
GroupUpdate(comp::group::ChangeNotification<sync::Uid>),
|
||||||
// Indicate to the client that they are invited to join a group
|
/// Indicate to the client that they are invited to join a group
|
||||||
GroupInvite {
|
GroupInvite {
|
||||||
inviter: sync::Uid,
|
inviter: sync::Uid,
|
||||||
timeout: std::time::Duration,
|
timeout: std::time::Duration,
|
||||||
},
|
},
|
||||||
// Indicate to the client that their sent invite was not invalid and is currently pending
|
/// Indicate to the client that their sent invite was not invalid and is
|
||||||
|
/// currently pending
|
||||||
InvitePending(sync::Uid),
|
InvitePending(sync::Uid),
|
||||||
// Note: this could potentially include all the failure cases such as inviting yourself in
|
/// Note: this could potentially include all the failure cases such as
|
||||||
// which case the `InvitePending` message could be removed and the client could consider their
|
/// inviting yourself in which case the `InvitePending` message could be
|
||||||
// invite pending until they receive this message
|
/// removed and the client could consider their invite pending until
|
||||||
// Indicate to the client the result of their invite
|
/// they receive this message Indicate to the client the result of their
|
||||||
|
/// invite
|
||||||
InviteComplete {
|
InviteComplete {
|
||||||
target: sync::Uid,
|
target: sync::Uid,
|
||||||
answer: InviteAnswer,
|
answer: InviteAnswer,
|
||||||
@ -108,11 +101,7 @@ pub enum ServerInGame {
|
|||||||
SetViewDistance(u32),
|
SetViewDistance(u32),
|
||||||
Outcomes(Vec<Outcome>),
|
Outcomes(Vec<Outcome>),
|
||||||
Knockback(Vec3<f32>),
|
Knockback(Vec3<f32>),
|
||||||
}
|
// Always possible
|
||||||
|
|
||||||
/// Messages sent from the server to the client
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
pub enum ServerGeneral {
|
|
||||||
PlayerListUpdate(PlayerListUpdate),
|
PlayerListUpdate(PlayerListUpdate),
|
||||||
/// A message to go into the client chat box. The client is responsible for
|
/// A message to go into the client chat box. The client is responsible for
|
||||||
/// formatting the message and turning it into a speech bubble.
|
/// formatting the message and turning it into a speech bubble.
|
||||||
@ -190,6 +179,61 @@ pub enum RegisterError {
|
|||||||
//TODO: InvalidAlias,
|
//TODO: InvalidAlias,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ServerMsg {
|
||||||
|
pub fn verify(
|
||||||
|
&self,
|
||||||
|
c_type: ClientType,
|
||||||
|
registered: bool,
|
||||||
|
in_game: Option<super::ClientInGame>,
|
||||||
|
) -> bool {
|
||||||
|
match self {
|
||||||
|
ServerMsg::Info(_) | ServerMsg::Init(_) | ServerMsg::RegisterAnswer(_) => {
|
||||||
|
!registered && in_game.is_none()
|
||||||
|
},
|
||||||
|
ServerMsg::General(g) => {
|
||||||
|
registered
|
||||||
|
&& match g {
|
||||||
|
//Character Screen related
|
||||||
|
ServerGeneral::CharacterDataLoadError(_)
|
||||||
|
| ServerGeneral::CharacterListUpdate(_)
|
||||||
|
| ServerGeneral::CharacterActionError(_) => {
|
||||||
|
c_type != ClientType::ChatOnly && in_game.is_none()
|
||||||
|
},
|
||||||
|
ServerGeneral::CharacterSuccess => {
|
||||||
|
c_type == ClientType::Game && in_game.is_none()
|
||||||
|
},
|
||||||
|
//Ingame related
|
||||||
|
ServerGeneral::GroupUpdate(_)
|
||||||
|
| ServerGeneral::GroupInvite { .. }
|
||||||
|
| ServerGeneral::InvitePending(_)
|
||||||
|
| ServerGeneral::InviteComplete { .. }
|
||||||
|
| ServerGeneral::ExitInGameSuccess
|
||||||
|
| ServerGeneral::InventoryUpdate(_, _)
|
||||||
|
| ServerGeneral::TerrainChunkUpdate { .. }
|
||||||
|
| ServerGeneral::TerrainBlockUpdates(_)
|
||||||
|
| ServerGeneral::SetViewDistance(_)
|
||||||
|
| ServerGeneral::Outcomes(_)
|
||||||
|
| ServerGeneral::Knockback(_) => {
|
||||||
|
c_type == ClientType::Game && in_game.is_some()
|
||||||
|
},
|
||||||
|
// Always possible
|
||||||
|
ServerGeneral::PlayerListUpdate(_)
|
||||||
|
| ServerGeneral::ChatMsg(_)
|
||||||
|
| ServerGeneral::SetPlayerEntity(_)
|
||||||
|
| ServerGeneral::TimeOfDay(_)
|
||||||
|
| ServerGeneral::EntitySync(_)
|
||||||
|
| ServerGeneral::CompSync(_)
|
||||||
|
| ServerGeneral::CreateEntity(_)
|
||||||
|
| ServerGeneral::DeleteEntity(_)
|
||||||
|
| ServerGeneral::Disconnect(_)
|
||||||
|
| ServerGeneral::Notification(_) => true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ServerMsg::Ping(_) => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<AuthClientError> for RegisterError {
|
impl From<AuthClientError> for RegisterError {
|
||||||
fn from(err: AuthClientError) -> Self { Self::AuthError(err.to_string()) }
|
fn from(err: AuthClientError) -> Self { Self::AuthError(err.to_string()) }
|
||||||
}
|
}
|
||||||
@ -210,14 +254,6 @@ impl Into<ServerMsg> for ServerRegisterAnswer {
|
|||||||
fn into(self) -> ServerMsg { ServerMsg::RegisterAnswer(self) }
|
fn into(self) -> ServerMsg { ServerMsg::RegisterAnswer(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<ServerMsg> for ServerCharacterScreen {
|
|
||||||
fn into(self) -> ServerMsg { ServerMsg::CharacterScreen(self) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<ServerMsg> for ServerInGame {
|
|
||||||
fn into(self) -> ServerMsg { ServerMsg::InGame(self) }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Into<ServerMsg> for ServerGeneral {
|
impl Into<ServerMsg> for ServerGeneral {
|
||||||
fn into(self) -> ServerMsg { ServerMsg::General(self) }
|
fn into(self) -> ServerMsg { ServerMsg::General(self) }
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use common::msg::{ClientIngame, ClientType, ServerMsg};
|
use common::msg::{ClientInGame, ClientType, ServerGeneral, ServerMsg};
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use network::{Participant, Stream};
|
use network::{Participant, Stream};
|
||||||
use serde::{de::DeserializeOwned, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
@ -11,7 +11,7 @@ use vek::*;
|
|||||||
pub struct Client {
|
pub struct Client {
|
||||||
pub registered: bool,
|
pub registered: bool,
|
||||||
pub client_type: ClientType,
|
pub client_type: ClientType,
|
||||||
pub in_game: Option<ClientIngame>,
|
pub in_game: Option<ClientInGame>,
|
||||||
pub participant: Option<Participant>,
|
pub participant: Option<Participant>,
|
||||||
pub general_stream: Stream,
|
pub general_stream: Stream,
|
||||||
pub ping_stream: Stream,
|
pub ping_stream: Stream,
|
||||||
@ -59,16 +59,38 @@ impl Client {
|
|||||||
ServerMsg::RegisterAnswer(msg) => {
|
ServerMsg::RegisterAnswer(msg) => {
|
||||||
Self::internal_send(&mut self.network_error, &mut self.register_stream, &msg)
|
Self::internal_send(&mut self.network_error, &mut self.register_stream, &msg)
|
||||||
},
|
},
|
||||||
ServerMsg::CharacterScreen(msg) => Self::internal_send(
|
|
||||||
&mut self.network_error,
|
|
||||||
&mut self.character_screen_stream,
|
|
||||||
&msg,
|
|
||||||
),
|
|
||||||
ServerMsg::InGame(msg) => {
|
|
||||||
Self::internal_send(&mut self.network_error, &mut self.in_game_stream, &msg)
|
|
||||||
},
|
|
||||||
ServerMsg::General(msg) => {
|
ServerMsg::General(msg) => {
|
||||||
Self::internal_send(&mut self.network_error, &mut self.general_stream, &msg)
|
let stream = match &msg {
|
||||||
|
//Character Screen related
|
||||||
|
ServerGeneral::CharacterDataLoadError(_)
|
||||||
|
| ServerGeneral::CharacterListUpdate(_)
|
||||||
|
| ServerGeneral::CharacterActionError(_)
|
||||||
|
| ServerGeneral::CharacterSuccess => &mut self.character_screen_stream,
|
||||||
|
//Ingame related
|
||||||
|
ServerGeneral::GroupUpdate(_)
|
||||||
|
| ServerGeneral::GroupInvite { .. }
|
||||||
|
| ServerGeneral::InvitePending(_)
|
||||||
|
| ServerGeneral::InviteComplete { .. }
|
||||||
|
| ServerGeneral::ExitInGameSuccess
|
||||||
|
| ServerGeneral::InventoryUpdate(_, _)
|
||||||
|
| ServerGeneral::TerrainChunkUpdate { .. }
|
||||||
|
| ServerGeneral::TerrainBlockUpdates(_)
|
||||||
|
| ServerGeneral::SetViewDistance(_)
|
||||||
|
| ServerGeneral::Outcomes(_)
|
||||||
|
| ServerGeneral::Knockback(_) => &mut self.in_game_stream,
|
||||||
|
// Always possible
|
||||||
|
ServerGeneral::PlayerListUpdate(_)
|
||||||
|
| ServerGeneral::ChatMsg(_)
|
||||||
|
| ServerGeneral::SetPlayerEntity(_)
|
||||||
|
| ServerGeneral::TimeOfDay(_)
|
||||||
|
| ServerGeneral::EntitySync(_)
|
||||||
|
| ServerGeneral::CompSync(_)
|
||||||
|
| ServerGeneral::CreateEntity(_)
|
||||||
|
| ServerGeneral::DeleteEntity(_)
|
||||||
|
| ServerGeneral::Disconnect(_)
|
||||||
|
| ServerGeneral::Notification(_) => &mut self.general_stream,
|
||||||
|
};
|
||||||
|
Self::internal_send(&mut self.network_error, stream, &msg)
|
||||||
},
|
},
|
||||||
ServerMsg::Ping(msg) => {
|
ServerMsg::Ping(msg) => {
|
||||||
Self::internal_send(&mut self.network_error, &mut self.ping_stream, &msg)
|
Self::internal_send(&mut self.network_error, &mut self.ping_stream, &msg)
|
||||||
|
@ -12,7 +12,7 @@ use common::{
|
|||||||
cmd::{ChatCommand, CHAT_COMMANDS, CHAT_SHORTCUTS},
|
cmd::{ChatCommand, CHAT_COMMANDS, CHAT_SHORTCUTS},
|
||||||
comp::{self, ChatType, Item, LightEmitter, WaypointArea},
|
comp::{self, ChatType, Item, LightEmitter, WaypointArea},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
msg::{DisconnectReason, Notification, PlayerListUpdate, ServerGeneral, ServerInGame},
|
msg::{DisconnectReason, Notification, PlayerListUpdate, ServerGeneral},
|
||||||
npc::{self, get_npc_name},
|
npc::{self, get_npc_name},
|
||||||
state::TimeOfDay,
|
state::TimeOfDay,
|
||||||
sync::{Uid, WorldSyncExt},
|
sync::{Uid, WorldSyncExt},
|
||||||
@ -669,7 +669,9 @@ fn handle_spawn(
|
|||||||
.try_map(|e| uids.get(e).copied())
|
.try_map(|e| uids.get(e).copied())
|
||||||
.map(|g| (g, c))
|
.map(|g| (g, c))
|
||||||
})
|
})
|
||||||
.map(|(g, c)| c.send_msg(ServerInGame::GroupUpdate(g)));
|
.map(|(g, c)| {
|
||||||
|
c.send_msg(ServerGeneral::GroupUpdate(g))
|
||||||
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} else if let Some(group) = match alignment {
|
} else if let Some(group) = match alignment {
|
||||||
|
@ -12,7 +12,7 @@ use common::{
|
|||||||
Player, Pos, Stats,
|
Player, Pos, Stats,
|
||||||
},
|
},
|
||||||
lottery::Lottery,
|
lottery::Lottery,
|
||||||
msg::{PlayerListUpdate, ServerGeneral, ServerInGame},
|
msg::{PlayerListUpdate, ServerGeneral},
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
state::BlockChange,
|
state::BlockChange,
|
||||||
sync::{Uid, UidAllocator, WorldSyncExt},
|
sync::{Uid, UidAllocator, WorldSyncExt},
|
||||||
@ -44,7 +44,7 @@ pub fn handle_knockback(server: &Server, entity: EcsEntity, impulse: Vec3<f32>)
|
|||||||
}
|
}
|
||||||
let mut clients = state.ecs().write_storage::<Client>();
|
let mut clients = state.ecs().write_storage::<Client>();
|
||||||
if let Some(client) = clients.get_mut(entity) {
|
if let Some(client) = clients.get_mut(entity) {
|
||||||
client.send_msg(ServerInGame::Knockback(impulse));
|
client.send_msg(ServerGeneral::Knockback(impulse));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use common::{
|
|||||||
group::{self, Group, GroupManager, Invite, PendingInvites},
|
group::{self, Group, GroupManager, Invite, PendingInvites},
|
||||||
ChatType, GroupManip,
|
ChatType, GroupManip,
|
||||||
},
|
},
|
||||||
msg::{InviteAnswer, ServerInGame},
|
msg::{InviteAnswer, ServerGeneral},
|
||||||
sync,
|
sync,
|
||||||
sync::WorldSyncExt,
|
sync::WorldSyncExt,
|
||||||
};
|
};
|
||||||
@ -155,7 +155,7 @@ pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupMani
|
|||||||
(clients.get_mut(invitee), uids.get(entity).copied())
|
(clients.get_mut(invitee), uids.get(entity).copied())
|
||||||
{
|
{
|
||||||
if send_invite() {
|
if send_invite() {
|
||||||
client.send_msg(ServerInGame::GroupInvite {
|
client.send_msg(ServerGeneral::GroupInvite {
|
||||||
inviter,
|
inviter,
|
||||||
timeout: PRESENTED_INVITE_TIMEOUT_DUR,
|
timeout: PRESENTED_INVITE_TIMEOUT_DUR,
|
||||||
});
|
});
|
||||||
@ -171,7 +171,7 @@ pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupMani
|
|||||||
// Notify inviter that the invite is pending
|
// Notify inviter that the invite is pending
|
||||||
if invite_sent {
|
if invite_sent {
|
||||||
if let Some(client) = clients.get_mut(entity) {
|
if let Some(client) = clients.get_mut(entity) {
|
||||||
client.send_msg(ServerInGame::InvitePending(uid));
|
client.send_msg(ServerGeneral::InvitePending(uid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -196,7 +196,7 @@ pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupMani
|
|||||||
if let (Some(client), Some(target)) =
|
if let (Some(client), Some(target)) =
|
||||||
(clients.get_mut(inviter), uids.get(entity).copied())
|
(clients.get_mut(inviter), uids.get(entity).copied())
|
||||||
{
|
{
|
||||||
client.send_msg(ServerInGame::InviteComplete {
|
client.send_msg(ServerGeneral::InviteComplete {
|
||||||
target,
|
target,
|
||||||
answer: InviteAnswer::Accepted,
|
answer: InviteAnswer::Accepted,
|
||||||
})
|
})
|
||||||
@ -217,7 +217,7 @@ pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupMani
|
|||||||
.try_map(|e| uids.get(e).copied())
|
.try_map(|e| uids.get(e).copied())
|
||||||
.map(|g| (g, c))
|
.map(|g| (g, c))
|
||||||
})
|
})
|
||||||
.map(|(g, c)| c.send_msg(ServerInGame::GroupUpdate(g)));
|
.map(|(g, c)| c.send_msg(ServerGeneral::GroupUpdate(g)));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -244,7 +244,7 @@ pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupMani
|
|||||||
if let (Some(client), Some(target)) =
|
if let (Some(client), Some(target)) =
|
||||||
(clients.get_mut(inviter), uids.get(entity).copied())
|
(clients.get_mut(inviter), uids.get(entity).copied())
|
||||||
{
|
{
|
||||||
client.send_msg(ServerInGame::InviteComplete {
|
client.send_msg(ServerGeneral::InviteComplete {
|
||||||
target,
|
target,
|
||||||
answer: InviteAnswer::Declined,
|
answer: InviteAnswer::Declined,
|
||||||
})
|
})
|
||||||
@ -269,7 +269,7 @@ pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupMani
|
|||||||
.try_map(|e| uids.get(e).copied())
|
.try_map(|e| uids.get(e).copied())
|
||||||
.map(|g| (g, c))
|
.map(|g| (g, c))
|
||||||
})
|
})
|
||||||
.map(|(g, c)| c.send_msg(ServerInGame::GroupUpdate(g)));
|
.map(|(g, c)| c.send_msg(ServerGeneral::GroupUpdate(g)));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -336,7 +336,7 @@ pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupMani
|
|||||||
.try_map(|e| uids.get(e).copied())
|
.try_map(|e| uids.get(e).copied())
|
||||||
.map(|g| (g, c))
|
.map(|g| (g, c))
|
||||||
})
|
})
|
||||||
.map(|(g, c)| c.send_msg(ServerInGame::GroupUpdate(g)));
|
.map(|(g, c)| c.send_msg(ServerGeneral::GroupUpdate(g)));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupMani
|
|||||||
.try_map(|e| uids.get(e).copied())
|
.try_map(|e| uids.get(e).copied())
|
||||||
.map(|g| (g, c))
|
.map(|g| (g, c))
|
||||||
})
|
})
|
||||||
.map(|(g, c)| c.send_msg(ServerInGame::GroupUpdate(g)));
|
.map(|(g, c)| c.send_msg(ServerGeneral::GroupUpdate(g)));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
// Tell them they are the leader
|
// Tell them they are the leader
|
||||||
|
@ -5,7 +5,7 @@ use common::{
|
|||||||
slot::{self, Slot},
|
slot::{self, Slot},
|
||||||
Pos, MAX_PICKUP_RANGE_SQR,
|
Pos, MAX_PICKUP_RANGE_SQR,
|
||||||
},
|
},
|
||||||
msg::ServerInGame,
|
msg::ServerGeneral,
|
||||||
recipe::default_recipe_book,
|
recipe::default_recipe_book,
|
||||||
sync::{Uid, WorldSyncExt},
|
sync::{Uid, WorldSyncExt},
|
||||||
vol::ReadVol,
|
vol::ReadVol,
|
||||||
@ -281,7 +281,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
|
|||||||
.map(|g| (g, c))
|
.map(|g| (g, c))
|
||||||
})
|
})
|
||||||
.map(|(g, c)| {
|
.map(|(g, c)| {
|
||||||
c.send_msg(ServerInGame::GroupUpdate(g))
|
c.send_msg(ServerGeneral::GroupUpdate(g))
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -5,7 +5,7 @@ use crate::{
|
|||||||
use common::{
|
use common::{
|
||||||
comp,
|
comp,
|
||||||
comp::{group, Player},
|
comp::{group, Player},
|
||||||
msg::{PlayerListUpdate, ServerGeneral, ServerInGame},
|
msg::{PlayerListUpdate, ServerGeneral},
|
||||||
span,
|
span,
|
||||||
sync::{Uid, UidAllocator},
|
sync::{Uid, UidAllocator},
|
||||||
};
|
};
|
||||||
@ -34,7 +34,7 @@ pub fn handle_exit_ingame(server: &mut Server, entity: EcsEntity) {
|
|||||||
if let (Some(mut client), Some(uid), Some(player)) = (maybe_client, maybe_uid, maybe_player) {
|
if let (Some(mut client), Some(uid), Some(player)) = (maybe_client, maybe_uid, maybe_player) {
|
||||||
// Tell client its request was successful
|
// Tell client its request was successful
|
||||||
client.in_game = None;
|
client.in_game = None;
|
||||||
client.send_msg(ServerInGame::ExitInGameSuccess);
|
client.send_msg(ServerGeneral::ExitInGameSuccess);
|
||||||
|
|
||||||
let entity_builder = state.ecs_mut().create_entity().with(client).with(player);
|
let entity_builder = state.ecs_mut().create_entity().with(client).with(player);
|
||||||
|
|
||||||
|
@ -47,8 +47,7 @@ use common::{
|
|||||||
comp::{self, ChatType},
|
comp::{self, ChatType},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
msg::{
|
msg::{
|
||||||
ClientType, DisconnectReason, ServerCharacterScreen, ServerGeneral, ServerInfo, ServerInit,
|
ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerInit, ServerMsg, WorldMapMsg,
|
||||||
ServerMsg, WorldMapMsg,
|
|
||||||
},
|
},
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
recipe::default_recipe_book,
|
recipe::default_recipe_book,
|
||||||
@ -527,11 +526,11 @@ impl Server {
|
|||||||
CharacterLoaderResponseType::CharacterList(result) => match result {
|
CharacterLoaderResponseType::CharacterList(result) => match result {
|
||||||
Ok(character_list_data) => self.notify_client(
|
Ok(character_list_data) => self.notify_client(
|
||||||
query_result.entity,
|
query_result.entity,
|
||||||
ServerCharacterScreen::CharacterListUpdate(character_list_data),
|
ServerGeneral::CharacterListUpdate(character_list_data),
|
||||||
),
|
),
|
||||||
Err(error) => self.notify_client(
|
Err(error) => self.notify_client(
|
||||||
query_result.entity,
|
query_result.entity,
|
||||||
ServerCharacterScreen::CharacterActionError(error.to_string()),
|
ServerGeneral::CharacterActionError(error.to_string()),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
CharacterLoaderResponseType::CharacterData(result) => {
|
CharacterLoaderResponseType::CharacterData(result) => {
|
||||||
@ -546,7 +545,7 @@ impl Server {
|
|||||||
// to display
|
// to display
|
||||||
self.notify_client(
|
self.notify_client(
|
||||||
query_result.entity,
|
query_result.entity,
|
||||||
ServerCharacterScreen::CharacterDataLoadError(error.to_string()),
|
ServerGeneral::CharacterDataLoadError(error.to_string()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Clean up the entity data on the server
|
// Clean up the entity data on the server
|
||||||
|
@ -5,10 +5,7 @@ use common::{
|
|||||||
character::CharacterId,
|
character::CharacterId,
|
||||||
comp,
|
comp,
|
||||||
effect::Effect,
|
effect::Effect,
|
||||||
msg::{
|
msg::{CharacterInfo, ClientInGame, PlayerListUpdate, ServerGeneral, ServerMsg},
|
||||||
CharacterInfo, ClientIngame, PlayerListUpdate, ServerCharacterScreen, ServerGeneral,
|
|
||||||
ServerInGame, ServerMsg,
|
|
||||||
},
|
|
||||||
state::State,
|
state::State,
|
||||||
sync::{Uid, UidAllocator, WorldSyncExt},
|
sync::{Uid, UidAllocator, WorldSyncExt},
|
||||||
util::Dir,
|
util::Dir,
|
||||||
@ -63,7 +60,7 @@ pub trait StateExt {
|
|||||||
/// Iterates over registered clients and send each `ServerMsg`
|
/// Iterates over registered clients and send each `ServerMsg`
|
||||||
fn send_chat(&self, msg: comp::UnresolvedChatMsg);
|
fn send_chat(&self, msg: comp::UnresolvedChatMsg);
|
||||||
fn notify_registered_clients(&self, msg: ServerGeneral);
|
fn notify_registered_clients(&self, msg: ServerGeneral);
|
||||||
fn notify_in_game_clients(&self, msg: ServerInGame);
|
fn notify_in_game_clients(&self, msg: ServerGeneral);
|
||||||
/// Delete an entity, recording the deletion in [`DeletedEntities`]
|
/// Delete an entity, recording the deletion in [`DeletedEntities`]
|
||||||
fn delete_entity_recorded(
|
fn delete_entity_recorded(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -220,8 +217,8 @@ impl StateExt for State {
|
|||||||
|
|
||||||
// Tell the client its request was successful.
|
// Tell the client its request was successful.
|
||||||
if let Some(client) = self.ecs().write_storage::<Client>().get_mut(entity) {
|
if let Some(client) = self.ecs().write_storage::<Client>().get_mut(entity) {
|
||||||
client.in_game = Some(ClientIngame::Character);
|
client.in_game = Some(ClientInGame::Character);
|
||||||
client.send_msg(ServerCharacterScreen::CharacterSuccess)
|
client.send_msg(ServerGeneral::CharacterSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +365,7 @@ impl StateExt for State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sends the message to all clients playing in game
|
/// Sends the message to all clients playing in game
|
||||||
fn notify_in_game_clients(&self, msg: ServerInGame) {
|
fn notify_in_game_clients(&self, msg: ServerGeneral) {
|
||||||
let msg: ServerMsg = msg.into();
|
let msg: ServerMsg = msg.into();
|
||||||
for client in (&mut self.ecs().write_storage::<Client>())
|
for client in (&mut self.ecs().write_storage::<Client>())
|
||||||
.join()
|
.join()
|
||||||
@ -401,7 +398,7 @@ impl StateExt for State {
|
|||||||
.try_map(|e| uids.get(e).copied())
|
.try_map(|e| uids.get(e).copied())
|
||||||
.map(|g| (g, c))
|
.map(|g| (g, c))
|
||||||
})
|
})
|
||||||
.map(|(g, c)| c.send_msg(ServerInGame::GroupUpdate(g)));
|
.map(|(g, c)| c.send_msg(ServerGeneral::GroupUpdate(g)));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
comp::{ForceUpdate, Inventory, InventoryUpdate, Last, Ori, Player, Pos, Vel},
|
comp::{ForceUpdate, Inventory, InventoryUpdate, Last, Ori, Player, Pos, Vel},
|
||||||
msg::{ServerGeneral, ServerInGame},
|
msg::ServerGeneral,
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
region::{Event as RegionEvent, RegionMap},
|
region::{Event as RegionEvent, RegionMap},
|
||||||
span,
|
span,
|
||||||
@ -320,7 +320,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
|
|
||||||
// Sync inventories
|
// Sync inventories
|
||||||
for (client, inventory, update) in (&mut clients, &inventories, &inventory_updates).join() {
|
for (client, inventory, update) in (&mut clients, &inventories, &inventory_updates).join() {
|
||||||
client.send_msg(ServerInGame::InventoryUpdate(
|
client.send_msg(ServerGeneral::InventoryUpdate(
|
||||||
inventory.clone(),
|
inventory.clone(),
|
||||||
update.event(),
|
update.event(),
|
||||||
));
|
));
|
||||||
@ -341,7 +341,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
.cloned()
|
.cloned()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
if !outcomes.is_empty() {
|
if !outcomes.is_empty() {
|
||||||
client.send_msg(ServerInGame::Outcomes(outcomes));
|
client.send_msg(ServerGeneral::Outcomes(outcomes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outcomes.clear();
|
outcomes.clear();
|
||||||
|
@ -2,7 +2,7 @@ use super::SysTimer;
|
|||||||
use crate::client::Client;
|
use crate::client::Client;
|
||||||
use common::{
|
use common::{
|
||||||
comp::group::{Invite, PendingInvites},
|
comp::group::{Invite, PendingInvites},
|
||||||
msg::{InviteAnswer, ServerInGame},
|
msg::{InviteAnswer, ServerGeneral},
|
||||||
span,
|
span,
|
||||||
sync::Uid,
|
sync::Uid,
|
||||||
};
|
};
|
||||||
@ -54,7 +54,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
if let (Some(client), Some(target)) =
|
if let (Some(client), Some(target)) =
|
||||||
(clients.get_mut(*inviter), uids.get(invitee).copied())
|
(clients.get_mut(*inviter), uids.get(invitee).copied())
|
||||||
{
|
{
|
||||||
client.send_msg(ServerInGame::InviteComplete {
|
client.send_msg(ServerGeneral::InviteComplete {
|
||||||
target,
|
target,
|
||||||
answer: InviteAnswer::TimedOut,
|
answer: InviteAnswer::TimedOut,
|
||||||
})
|
})
|
||||||
|
@ -15,10 +15,9 @@ use common::{
|
|||||||
},
|
},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
msg::{
|
msg::{
|
||||||
validate_chat_msg, CharacterInfo, ChatMsgValidationError, ClientCharacterScreen,
|
validate_chat_msg, CharacterInfo, ChatMsgValidationError, ClientGeneral, ClientInGame,
|
||||||
ClientGeneral, ClientInGame, ClientIngame, ClientRegister, DisconnectReason, PingMsg,
|
ClientRegister, DisconnectReason, PingMsg, PlayerInfo, PlayerListUpdate, RegisterError,
|
||||||
PlayerInfo, PlayerListUpdate, RegisterError, ServerCharacterScreen, ServerGeneral,
|
ServerGeneral, ServerRegisterAnswer, MAX_BYTES_CHAT_MSG,
|
||||||
ServerInGame, ServerRegisterAnswer, MAX_BYTES_CHAT_MSG,
|
|
||||||
},
|
},
|
||||||
span,
|
span,
|
||||||
state::{BlockChange, Time},
|
state::{BlockChange, Time},
|
||||||
@ -79,6 +78,7 @@ impl Sys {
|
|||||||
.inc();
|
.inc();
|
||||||
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
server_emitter.emit(ServerEvent::ClientDisconnect(entity));
|
||||||
},
|
},
|
||||||
|
_ => unreachable!("not a client_general msg"),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -100,24 +100,24 @@ impl Sys {
|
|||||||
players: &mut WriteStorage<'_, Player>,
|
players: &mut WriteStorage<'_, Player>,
|
||||||
controllers: &mut WriteStorage<'_, Controller>,
|
controllers: &mut WriteStorage<'_, Controller>,
|
||||||
settings: &Read<'_, Settings>,
|
settings: &Read<'_, Settings>,
|
||||||
msg: ClientInGame,
|
msg: ClientGeneral,
|
||||||
) -> Result<(), crate::error::Error> {
|
) -> Result<(), crate::error::Error> {
|
||||||
if client.in_game.is_none() {
|
if client.in_game.is_none() {
|
||||||
debug!(?entity, "client is not in_game, ignoring msg");
|
debug!(?entity, "client is not in_game, ignoring msg");
|
||||||
trace!(?msg, "ignored msg content");
|
trace!(?msg, "ignored msg content");
|
||||||
if matches!(msg, ClientInGame::TerrainChunkRequest{ .. }) {
|
if matches!(msg, ClientGeneral::TerrainChunkRequest{ .. }) {
|
||||||
network_metrics.chunks_request_dropped.inc();
|
network_metrics.chunks_request_dropped.inc();
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
match msg {
|
match msg {
|
||||||
// Go back to registered state (char selection screen)
|
// Go back to registered state (char selection screen)
|
||||||
ClientInGame::ExitInGame => {
|
ClientGeneral::ExitInGame => {
|
||||||
client.in_game = None;
|
client.in_game = None;
|
||||||
server_emitter.emit(ServerEvent::ExitIngame { entity });
|
server_emitter.emit(ServerEvent::ExitIngame { entity });
|
||||||
client.send_msg(ServerInGame::ExitInGameSuccess);
|
client.send_msg(ServerGeneral::ExitInGameSuccess);
|
||||||
},
|
},
|
||||||
ClientInGame::SetViewDistance(view_distance) => {
|
ClientGeneral::SetViewDistance(view_distance) => {
|
||||||
players.get_mut(entity).map(|player| {
|
players.get_mut(entity).map(|player| {
|
||||||
player.view_distance = Some(
|
player.view_distance = Some(
|
||||||
settings
|
settings
|
||||||
@ -133,20 +133,20 @@ impl Sys {
|
|||||||
.map(|max| view_distance > max)
|
.map(|max| view_distance > max)
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
client.send_msg(ServerInGame::SetViewDistance(
|
client.send_msg(ServerGeneral::SetViewDistance(
|
||||||
settings.max_view_distance.unwrap_or(0),
|
settings.max_view_distance.unwrap_or(0),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientInGame::ControllerInputs(inputs) => {
|
ClientGeneral::ControllerInputs(inputs) => {
|
||||||
if let Some(ClientIngame::Character) = client.in_game {
|
if let Some(ClientInGame::Character) = client.in_game {
|
||||||
if let Some(controller) = controllers.get_mut(entity) {
|
if let Some(controller) = controllers.get_mut(entity) {
|
||||||
controller.inputs.update_with_new(inputs);
|
controller.inputs.update_with_new(inputs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientInGame::ControlEvent(event) => {
|
ClientGeneral::ControlEvent(event) => {
|
||||||
if let Some(ClientIngame::Character) = client.in_game {
|
if let Some(ClientInGame::Character) = client.in_game {
|
||||||
// Skip respawn if client entity is alive
|
// Skip respawn if client entity is alive
|
||||||
if let ControlEvent::Respawn = event {
|
if let ControlEvent::Respawn = event {
|
||||||
if stats.get(entity).map_or(true, |s| !s.is_dead) {
|
if stats.get(entity).map_or(true, |s| !s.is_dead) {
|
||||||
@ -159,15 +159,15 @@ impl Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientInGame::ControlAction(event) => {
|
ClientGeneral::ControlAction(event) => {
|
||||||
if let Some(ClientIngame::Character) = client.in_game {
|
if let Some(ClientInGame::Character) = client.in_game {
|
||||||
if let Some(controller) = controllers.get_mut(entity) {
|
if let Some(controller) = controllers.get_mut(entity) {
|
||||||
controller.actions.push(event);
|
controller.actions.push(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientInGame::PlayerPhysics { pos, vel, ori } => {
|
ClientGeneral::PlayerPhysics { pos, vel, ori } => {
|
||||||
if let Some(ClientIngame::Character) = client.in_game {
|
if let Some(ClientInGame::Character) = client.in_game {
|
||||||
if force_updates.get(entity).is_none()
|
if force_updates.get(entity).is_none()
|
||||||
&& stats.get(entity).map_or(true, |s| !s.is_dead)
|
&& stats.get(entity).map_or(true, |s| !s.is_dead)
|
||||||
{
|
{
|
||||||
@ -177,17 +177,17 @@ impl Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientInGame::BreakBlock(pos) => {
|
ClientGeneral::BreakBlock(pos) => {
|
||||||
if let Some(block) = can_build.get(entity).and_then(|_| terrain.get(pos).ok()) {
|
if let Some(block) = can_build.get(entity).and_then(|_| terrain.get(pos).ok()) {
|
||||||
block_changes.set(pos, block.into_vacant());
|
block_changes.set(pos, block.into_vacant());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientInGame::PlaceBlock(pos, block) => {
|
ClientGeneral::PlaceBlock(pos, block) => {
|
||||||
if can_build.get(entity).is_some() {
|
if can_build.get(entity).is_some() {
|
||||||
block_changes.try_set(pos, block);
|
block_changes.try_set(pos, block);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientInGame::TerrainChunkRequest { key } => {
|
ClientGeneral::TerrainChunkRequest { key } => {
|
||||||
let in_vd = if let (Some(view_distance), Some(pos)) = (
|
let in_vd = if let (Some(view_distance), Some(pos)) = (
|
||||||
players.get(entity).and_then(|p| p.view_distance),
|
players.get(entity).and_then(|p| p.view_distance),
|
||||||
positions.get(entity),
|
positions.get(entity),
|
||||||
@ -203,7 +203,7 @@ impl Sys {
|
|||||||
match terrain.get_key(key) {
|
match terrain.get_key(key) {
|
||||||
Some(chunk) => {
|
Some(chunk) => {
|
||||||
network_metrics.chunks_served_from_memory.inc();
|
network_metrics.chunks_served_from_memory.inc();
|
||||||
client.send_msg(ServerInGame::TerrainChunkUpdate {
|
client.send_msg(ServerGeneral::TerrainChunkUpdate {
|
||||||
key,
|
key,
|
||||||
chunk: Ok(Box::new(chunk.clone())),
|
chunk: Ok(Box::new(chunk.clone())),
|
||||||
})
|
})
|
||||||
@ -217,21 +217,22 @@ impl Sys {
|
|||||||
network_metrics.chunks_request_dropped.inc();
|
network_metrics.chunks_request_dropped.inc();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientInGame::UnlockSkill(skill) => {
|
ClientGeneral::UnlockSkill(skill) => {
|
||||||
stats
|
stats
|
||||||
.get_mut(entity)
|
.get_mut(entity)
|
||||||
.map(|s| s.skill_set.unlock_skill(skill));
|
.map(|s| s.skill_set.unlock_skill(skill));
|
||||||
},
|
},
|
||||||
ClientInGame::RefundSkill(skill) => {
|
ClientGeneral::RefundSkill(skill) => {
|
||||||
stats
|
stats
|
||||||
.get_mut(entity)
|
.get_mut(entity)
|
||||||
.map(|s| s.skill_set.refund_skill(skill));
|
.map(|s| s.skill_set.refund_skill(skill));
|
||||||
},
|
},
|
||||||
ClientInGame::UnlockSkillGroup(skill_group_type) => {
|
ClientGeneral::UnlockSkillGroup(skill_group_type) => {
|
||||||
stats
|
stats
|
||||||
.get_mut(entity)
|
.get_mut(entity)
|
||||||
.map(|s| s.skill_set.unlock_skill_group(skill_group_type));
|
.map(|s| s.skill_set.unlock_skill_group(skill_group_type));
|
||||||
},
|
},
|
||||||
|
_ => unreachable!("not a client_in_game msg"),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -247,17 +248,15 @@ impl Sys {
|
|||||||
players: &mut WriteStorage<'_, Player>,
|
players: &mut WriteStorage<'_, Player>,
|
||||||
editable_settings: &ReadExpect<'_, EditableSettings>,
|
editable_settings: &ReadExpect<'_, EditableSettings>,
|
||||||
alias_validator: &ReadExpect<'_, AliasValidator>,
|
alias_validator: &ReadExpect<'_, AliasValidator>,
|
||||||
msg: ClientCharacterScreen,
|
msg: ClientGeneral,
|
||||||
) -> Result<(), crate::error::Error> {
|
) -> Result<(), crate::error::Error> {
|
||||||
match msg {
|
match msg {
|
||||||
// Request spectator state
|
// Request spectator state
|
||||||
ClientCharacterScreen::Spectate if client.registered => {
|
ClientGeneral::Spectate if client.registered => {
|
||||||
client.in_game = Some(ClientIngame::Spectator)
|
client.in_game = Some(ClientInGame::Spectator)
|
||||||
},
|
},
|
||||||
ClientCharacterScreen::Spectate => {
|
ClientGeneral::Spectate => debug!("dropped Spectate msg from unregistered client"),
|
||||||
debug!("dropped Spectate msg from unregistered client")
|
ClientGeneral::Character(character_id)
|
||||||
},
|
|
||||||
ClientCharacterScreen::Character(character_id)
|
|
||||||
if client.registered && client.in_game.is_none() =>
|
if client.registered && client.in_game.is_none() =>
|
||||||
{
|
{
|
||||||
if let Some(player) = players.get(entity) {
|
if let Some(player) = players.get(entity) {
|
||||||
@ -296,27 +295,25 @@ impl Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
client.send_msg(ServerCharacterScreen::CharacterDataLoadError(String::from(
|
client.send_msg(ServerGeneral::CharacterDataLoadError(String::from(
|
||||||
"Failed to fetch player entity",
|
"Failed to fetch player entity",
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClientCharacterScreen::Character(_) => {
|
ClientGeneral::Character(_) => {
|
||||||
let registered = client.registered;
|
let registered = client.registered;
|
||||||
let in_game = client.in_game;
|
let in_game = client.in_game;
|
||||||
debug!(?registered, ?in_game, "dropped Character msg from client");
|
debug!(?registered, ?in_game, "dropped Character msg from client");
|
||||||
},
|
},
|
||||||
ClientCharacterScreen::RequestCharacterList => {
|
ClientGeneral::RequestCharacterList => {
|
||||||
if let Some(player) = players.get(entity) {
|
if let Some(player) = players.get(entity) {
|
||||||
character_loader.load_character_list(entity, player.uuid().to_string())
|
character_loader.load_character_list(entity, player.uuid().to_string())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientCharacterScreen::CreateCharacter { alias, tool, body } => {
|
ClientGeneral::CreateCharacter { alias, tool, body } => {
|
||||||
if let Err(error) = alias_validator.validate(&alias) {
|
if let Err(error) = alias_validator.validate(&alias) {
|
||||||
debug!(?error, ?alias, "denied alias as it contained a banned word");
|
debug!(?error, ?alias, "denied alias as it contained a banned word");
|
||||||
client.send_msg(ServerCharacterScreen::CharacterActionError(
|
client.send_msg(ServerGeneral::CharacterActionError(error.to_string()));
|
||||||
error.to_string(),
|
|
||||||
));
|
|
||||||
} else if let Some(player) = players.get(entity) {
|
} else if let Some(player) = players.get(entity) {
|
||||||
character_creator::create_character(
|
character_creator::create_character(
|
||||||
entity,
|
entity,
|
||||||
@ -328,7 +325,7 @@ impl Sys {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ClientCharacterScreen::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_loader.delete_character(
|
||||||
entity,
|
entity,
|
||||||
@ -337,6 +334,7 @@ impl Sys {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
_ => unreachable!("not a client_character_screen msg"),
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -379,7 +377,7 @@ impl Sys {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const INITIAL_VD: Option<u32> = Some(5); //will be changed after login
|
const INITIAL_VD: Option<u32> = Some(5); //will be changed after login
|
||||||
let player = Player::new(username.clone(), None, INITIAL_VD, uuid);
|
let player = Player::new(username, None, INITIAL_VD, uuid);
|
||||||
let is_admin = editable_settings.admins.contains(&uuid);
|
let is_admin = editable_settings.admins.contains(&uuid);
|
||||||
|
|
||||||
if !player.is_valid() {
|
if !player.is_valid() {
|
||||||
|
@ -4,7 +4,7 @@ use common::{
|
|||||||
comp::{self, bird_medium, Alignment, Player, Pos},
|
comp::{self, bird_medium, Alignment, Player, Pos},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
generation::get_npc_name,
|
generation::get_npc_name,
|
||||||
msg::ServerInGame,
|
msg::ServerGeneral,
|
||||||
npc::NPC_NAMES,
|
npc::NPC_NAMES,
|
||||||
span,
|
span,
|
||||||
state::TerrainChanges,
|
state::TerrainChanges,
|
||||||
@ -63,7 +63,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
Ok((chunk, supplement)) => (chunk, supplement),
|
Ok((chunk, supplement)) => (chunk, supplement),
|
||||||
Err(Some(entity)) => {
|
Err(Some(entity)) => {
|
||||||
if let Some(client) = clients.get_mut(entity) {
|
if let Some(client) = clients.get_mut(entity) {
|
||||||
client.send_msg(ServerInGame::TerrainChunkUpdate {
|
client.send_msg(ServerGeneral::TerrainChunkUpdate {
|
||||||
key,
|
key,
|
||||||
chunk: Err(()),
|
chunk: Err(()),
|
||||||
});
|
});
|
||||||
@ -90,7 +90,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
.magnitude_squared();
|
.magnitude_squared();
|
||||||
|
|
||||||
if adjusted_dist_sqr <= view_distance.pow(2) {
|
if adjusted_dist_sqr <= view_distance.pow(2) {
|
||||||
client.send_msg(ServerInGame::TerrainChunkUpdate {
|
client.send_msg(ServerGeneral::TerrainChunkUpdate {
|
||||||
key,
|
key,
|
||||||
chunk: Ok(Box::new(chunk.clone())),
|
chunk: Ok(Box::new(chunk.clone())),
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,7 @@ use super::SysTimer;
|
|||||||
use crate::client::Client;
|
use crate::client::Client;
|
||||||
use common::{
|
use common::{
|
||||||
comp::{Player, Pos},
|
comp::{Player, Pos},
|
||||||
msg::ServerInGame,
|
msg::ServerGeneral,
|
||||||
span,
|
span,
|
||||||
state::TerrainChanges,
|
state::TerrainChanges,
|
||||||
terrain::TerrainGrid,
|
terrain::TerrainGrid,
|
||||||
@ -38,7 +38,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
.map(|vd| super::terrain::chunk_in_vd(pos.0, *chunk_key, &terrain, vd))
|
.map(|vd| super::terrain::chunk_in_vd(pos.0, *chunk_key, &terrain, vd))
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
{
|
{
|
||||||
client.send_msg(ServerInGame::TerrainChunkUpdate {
|
client.send_msg(ServerGeneral::TerrainChunkUpdate {
|
||||||
key: *chunk_key,
|
key: *chunk_key,
|
||||||
chunk: Ok(Box::new(match terrain.get_key(*chunk_key) {
|
chunk: Ok(Box::new(match terrain.get_key(*chunk_key) {
|
||||||
Some(chunk) => chunk.clone(),
|
Some(chunk) => chunk.clone(),
|
||||||
@ -51,7 +51,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
|
|
||||||
// TODO: Don't send all changed blocks to all clients
|
// TODO: Don't send all changed blocks to all clients
|
||||||
// Sync changed blocks
|
// Sync changed blocks
|
||||||
let msg = ServerInGame::TerrainBlockUpdates(terrain_changes.modified_blocks.clone());
|
let msg = ServerGeneral::TerrainBlockUpdates(terrain_changes.modified_blocks.clone());
|
||||||
for (player, client) in (&players, &mut clients).join() {
|
for (player, client) in (&players, &mut clients).join() {
|
||||||
if player.view_distance.is_some() {
|
if player.view_distance.is_some() {
|
||||||
client.send_msg(msg.clone());
|
client.send_msg(msg.clone());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user