mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Better formatting
Former-commit-id: 4316514f4f58dca8ed21dae00fad7a6df36b9ff1
This commit is contained in:
parent
7fc2b3490c
commit
df7a145bbc
@ -4,28 +4,21 @@ pub mod error;
|
||||
pub mod input;
|
||||
|
||||
// Reexports
|
||||
pub use specs::Entity as EcsEntity;
|
||||
pub use crate::{error::Error, input::Input};
|
||||
pub use specs::join::Join;
|
||||
pub use crate::{
|
||||
error::Error,
|
||||
input::Input,
|
||||
};
|
||||
pub use specs::Entity as EcsEntity;
|
||||
|
||||
use std::{
|
||||
time::Duration,
|
||||
net::SocketAddr,
|
||||
collections::HashSet,
|
||||
};
|
||||
use vek::*;
|
||||
use threadpool::ThreadPool;
|
||||
use specs::Builder;
|
||||
use common::{
|
||||
comp,
|
||||
msg::{ClientMsg, ClientState, ServerMsg},
|
||||
net::PostBox,
|
||||
state::State,
|
||||
terrain::TerrainChunk,
|
||||
net::PostBox,
|
||||
msg::{ClientState, ClientMsg, ServerMsg},
|
||||
};
|
||||
use specs::Builder;
|
||||
use std::{collections::HashSet, net::SocketAddr, time::Duration};
|
||||
use threadpool::ThreadPool;
|
||||
use vek::*;
|
||||
|
||||
const SERVER_TIMEOUT: f64 = 20.0; // Seconds
|
||||
|
||||
@ -51,20 +44,23 @@ pub struct Client {
|
||||
impl Client {
|
||||
/// Create a new `Client`.
|
||||
#[allow(dead_code)]
|
||||
pub fn new<A: Into<SocketAddr>>(
|
||||
addr: A,
|
||||
view_distance: u64,
|
||||
) -> Result<Self, Error> {
|
||||
pub fn new<A: Into<SocketAddr>>(addr: A, view_distance: u64) -> Result<Self, Error> {
|
||||
let mut client_state = ClientState::Connected;
|
||||
let mut postbox = PostBox::to(addr)?;
|
||||
|
||||
// Wait for initial sync
|
||||
let (state, entity) = match postbox.next_message() {
|
||||
Some(ServerMsg::InitialSync { ecs_state, entity_uid }) => {
|
||||
Some(ServerMsg::InitialSync {
|
||||
ecs_state,
|
||||
entity_uid,
|
||||
}) => {
|
||||
let mut state = State::from_state_package(ecs_state);
|
||||
let entity = state.ecs().entity_from_uid(entity_uid).ok_or(Error::ServerWentMad)?;
|
||||
let entity = state
|
||||
.ecs()
|
||||
.entity_from_uid(entity_uid)
|
||||
.ok_or(Error::ServerWentMad)?;
|
||||
(state, entity)
|
||||
},
|
||||
}
|
||||
_ => return Err(Error::ServerWentMad),
|
||||
};
|
||||
|
||||
@ -94,15 +90,21 @@ impl Client {
|
||||
/// computationally expensive operations that run outside of the main thread (i.e: threads that
|
||||
/// block on I/O operations are exempt).
|
||||
#[allow(dead_code)]
|
||||
pub fn thread_pool(&self) -> &threadpool::ThreadPool { &self.thread_pool }
|
||||
pub fn thread_pool(&self) -> &threadpool::ThreadPool {
|
||||
&self.thread_pool
|
||||
}
|
||||
|
||||
/// Get a reference to the client's game state.
|
||||
#[allow(dead_code)]
|
||||
pub fn state(&self) -> &State { &self.state }
|
||||
pub fn state(&self) -> &State {
|
||||
&self.state
|
||||
}
|
||||
|
||||
/// Get a mutable reference to the client's game state.
|
||||
#[allow(dead_code)]
|
||||
pub fn state_mut(&mut self) -> &mut State { &mut self.state }
|
||||
pub fn state_mut(&mut self) -> &mut State {
|
||||
&mut self.state
|
||||
}
|
||||
|
||||
/// Get the player's entity
|
||||
#[allow(dead_code)]
|
||||
@ -147,9 +149,12 @@ impl Client {
|
||||
println!("Chunk at {:?}", k);
|
||||
});
|
||||
|
||||
self.state.write_component(self.entity, comp::Control {
|
||||
self.state.write_component(
|
||||
self.entity,
|
||||
comp::Control {
|
||||
move_dir: input.move_dir,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
// Tick the client's LocalState (step 3)
|
||||
self.state.tick(dt);
|
||||
@ -161,28 +166,42 @@ impl Client {
|
||||
self.state.read_storage().get(self.entity).cloned(),
|
||||
) {
|
||||
(Some(pos), Some(vel), Some(dir)) => {
|
||||
self.postbox.send_message(ClientMsg::PlayerPhysics { pos, vel, dir });
|
||||
},
|
||||
_ => {},
|
||||
self.postbox
|
||||
.send_message(ClientMsg::PlayerPhysics { pos, vel, dir });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Update the server about the player's currently playing animation and the previous one
|
||||
if let Some(animation_history) = self.state.read_storage::<comp::AnimationHistory>().get(self.entity).cloned() {
|
||||
if let Some(animation_history) = self
|
||||
.state
|
||||
.read_storage::<comp::AnimationHistory>()
|
||||
.get(self.entity)
|
||||
.cloned()
|
||||
{
|
||||
if Some(animation_history.current) != animation_history.last {
|
||||
self.postbox.send_message(ClientMsg::PlayerAnimation(animation_history));
|
||||
self.postbox
|
||||
.send_message(ClientMsg::PlayerAnimation(animation_history));
|
||||
}
|
||||
}
|
||||
|
||||
// Request chunks from the server
|
||||
if let Some(pos) = self.state.read_storage::<comp::phys::Pos>().get(self.entity) {
|
||||
if let Some(pos) = self
|
||||
.state
|
||||
.read_storage::<comp::phys::Pos>()
|
||||
.get(self.entity)
|
||||
{
|
||||
let chunk_pos = self.state.terrain().pos_key(pos.0.map(|e| e as i32));
|
||||
|
||||
for i in chunk_pos.x - 1..chunk_pos.x + 1 {
|
||||
for j in chunk_pos.y - 1..chunk_pos.y + 1 {
|
||||
for k in -1..3 {
|
||||
let key = chunk_pos + Vec3::new(i, j, k);
|
||||
if self.state.terrain().get_key(key).is_none() && !self.pending_chunks.contains(&key) {
|
||||
self.postbox.send_message(ClientMsg::TerrainChunkRequest { key });
|
||||
if self.state.terrain().get_key(key).is_none()
|
||||
&& !self.pending_chunks.contains(&key)
|
||||
{
|
||||
self.postbox
|
||||
.send_message(ClientMsg::TerrainChunkRequest { key });
|
||||
self.pending_chunks.insert(key);
|
||||
}
|
||||
}
|
||||
@ -217,7 +236,7 @@ impl Client {
|
||||
ServerMsg::InitialSync { .. } => return Err(Error::ServerWentMad),
|
||||
ServerMsg::Shutdown => return Err(Error::ServerShutdown),
|
||||
ServerMsg::Ping => self.postbox.send_message(ClientMsg::Pong),
|
||||
ServerMsg::Pong => {},
|
||||
ServerMsg::Pong => {}
|
||||
ServerMsg::Chat(msg) => frontend_events.push(Event::Chat(msg)),
|
||||
ServerMsg::SetPlayerEntity(uid) => self.entity = self.state.ecs().entity_from_uid(uid).unwrap(), // TODO: Don't unwrap here!
|
||||
ServerMsg::EcsSync(sync_package) => self.state.ecs_mut().sync_with_package(sync_package),
|
||||
@ -226,28 +245,28 @@ impl Client {
|
||||
self.state.write_component(entity, pos);
|
||||
self.state.write_component(entity, vel);
|
||||
self.state.write_component(entity, dir);
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
None => {}
|
||||
},
|
||||
ServerMsg::EntityAnimation { entity, animation_history } => match self.state.ecs().entity_from_uid(entity) {
|
||||
Some(entity) => {
|
||||
self.state.write_component(entity, animation_history);
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
None => {}
|
||||
},
|
||||
ServerMsg::TerrainChunkUpdate { key, chunk } => {
|
||||
self.state.insert_chunk(key, *chunk);
|
||||
self.pending_chunks.remove(&key);
|
||||
},
|
||||
}
|
||||
ServerMsg::StateAnswer(Ok(state)) => {
|
||||
self.client_state = state;
|
||||
},
|
||||
}
|
||||
ServerMsg::StateAnswer(Err((error, state))) => {
|
||||
self.client_state = state;
|
||||
},
|
||||
}
|
||||
ServerMsg::ForceState(state) => {
|
||||
self.client_state = state;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Some(err) = self.postbox.error() {
|
||||
|
@ -1,11 +1,11 @@
|
||||
use std::collections::HashMap;
|
||||
use specs::Entity as EcsEntity;
|
||||
use crate::Error;
|
||||
use common::{
|
||||
comp,
|
||||
msg::{ServerMsg, ClientMsg, ClientState, RequestStateError},
|
||||
msg::{ClientMsg, ClientState, RequestStateError, ServerMsg},
|
||||
net::PostBox,
|
||||
};
|
||||
use crate::Error;
|
||||
use specs::Entity as EcsEntity;
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub struct Client {
|
||||
pub client_state: ClientState,
|
||||
@ -19,17 +19,16 @@ impl Client {
|
||||
}
|
||||
pub fn allow_state(&mut self, new_state: ClientState) {
|
||||
self.client_state = new_state;
|
||||
self.postbox.send_message(ServerMsg::StateAnswer(
|
||||
Ok(new_state)));
|
||||
self.postbox
|
||||
.send_message(ServerMsg::StateAnswer(Ok(new_state)));
|
||||
}
|
||||
pub fn error_state(&mut self, error: RequestStateError) {
|
||||
self.postbox.send_message(ServerMsg::StateAnswer(
|
||||
Err((error, self.client_state))));
|
||||
self.postbox
|
||||
.send_message(ServerMsg::StateAnswer(Err((error, self.client_state))));
|
||||
}
|
||||
pub fn force_state(&mut self, new_state: ClientState) {
|
||||
self.client_state = new_state;
|
||||
self.postbox.send_message(ServerMsg::ForceState(
|
||||
new_state));
|
||||
self.postbox.send_message(ServerMsg::ForceState(new_state));
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +67,9 @@ impl Clients {
|
||||
|
||||
pub fn notify_ingame(&mut self, msg: ServerMsg) {
|
||||
for client in self.clients.values_mut() {
|
||||
if client.client_state == ClientState::Spectator || client.client_state == ClientState::Character {
|
||||
if client.client_state == ClientState::Spectator
|
||||
|| client.client_state == ClientState::Character
|
||||
{
|
||||
client.notify(msg.clone());
|
||||
}
|
||||
}
|
||||
@ -84,8 +85,10 @@ impl Clients {
|
||||
|
||||
pub fn notify_ingame_except(&mut self, except_entity: EcsEntity, msg: ServerMsg) {
|
||||
for (entity, client) in self.clients.iter_mut() {
|
||||
if (client.client_state == ClientState::Spectator || client.client_state == ClientState::Character)
|
||||
&& *entity != except_entity {
|
||||
if (client.client_state == ClientState::Spectator
|
||||
|| client.client_state == ClientState::Character)
|
||||
&& *entity != except_entity
|
||||
{
|
||||
client.notify(msg.clone());
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ use common::{comp, msg::ServerMsg};
|
||||
use specs::{join::Join, Entity as EcsEntity};
|
||||
use vek::*;
|
||||
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use scan_fmt::scan_fmt;
|
||||
/// Struct representing a command that a user can run from server chat
|
||||
|
@ -1,21 +1,24 @@
|
||||
#![feature(drain_filter)]
|
||||
|
||||
pub mod client;
|
||||
pub mod cmd;
|
||||
pub mod error;
|
||||
pub mod input;
|
||||
pub mod cmd;
|
||||
|
||||
// Reexports
|
||||
pub use crate::{error::Error, input::Input};
|
||||
|
||||
use crate::{client::{Client, Clients}, cmd::CHAT_COMMANDS};
|
||||
use crate::{
|
||||
client::{Client, Clients},
|
||||
cmd::CHAT_COMMANDS,
|
||||
};
|
||||
use common::{
|
||||
comp,
|
||||
msg::{ClientState, ClientMsg, ServerMsg, RequestStateError},
|
||||
comp::character::Animation,
|
||||
msg::{ClientMsg, ClientState, RequestStateError, ServerMsg},
|
||||
net::PostOffice,
|
||||
state::{State, Uid},
|
||||
terrain::TerrainChunk,
|
||||
comp::character::Animation,
|
||||
};
|
||||
use specs::{
|
||||
join::Join, saveload::MarkedBuilder, world::EntityBuilder as EcsEntityBuilder, Builder,
|
||||
@ -115,7 +118,12 @@ impl Server {
|
||||
.with(character)
|
||||
}
|
||||
|
||||
pub fn create_player_character(state: &mut State, entity: EcsEntity, client: &mut Client, character: comp::Character) {
|
||||
pub fn create_player_character(
|
||||
state: &mut State,
|
||||
entity: EcsEntity,
|
||||
client: &mut Client,
|
||||
character: comp::Character,
|
||||
) {
|
||||
state.write_component(entity, character);
|
||||
state.write_component(entity, comp::phys::Pos(Vec3::zero()));
|
||||
state.write_component(entity, comp::phys::Vel(Vec3::zero()));
|
||||
@ -124,10 +132,13 @@ impl Server {
|
||||
state.write_component(entity, comp::phys::ForceUpdate);
|
||||
|
||||
// Set initial animation
|
||||
state.write_component(entity, comp::AnimationHistory {
|
||||
state.write_component(
|
||||
entity,
|
||||
comp::AnimationHistory {
|
||||
last: None,
|
||||
current: Animation::Idle
|
||||
});
|
||||
current: Animation::Idle,
|
||||
},
|
||||
);
|
||||
|
||||
// Tell the client his request was successful
|
||||
client.notify(ServerMsg::StateAnswer(Ok(ClientState::Character)));
|
||||
@ -223,17 +234,10 @@ impl Server {
|
||||
// (All components Sphynx tracks)
|
||||
client.notify(ServerMsg::InitialSync {
|
||||
ecs_state: self.state.ecs().gen_state_package(),
|
||||
entity_uid: self.state
|
||||
.ecs()
|
||||
.uid_from_entity(entity)
|
||||
.unwrap()
|
||||
.into(),
|
||||
entity_uid: self.state.ecs().uid_from_entity(entity).unwrap().into(),
|
||||
});
|
||||
|
||||
self.clients.add(
|
||||
entity,
|
||||
client,
|
||||
);
|
||||
self.clients.add(entity, client);
|
||||
|
||||
frontend_events.push(Event::ClientConnected { entity });
|
||||
}
|
||||
@ -294,20 +298,21 @@ impl Server {
|
||||
},
|
||||
ClientMsg::Chat(msg) => match client.client_state {
|
||||
ClientState::Connected => client.error_state(RequestStateError::Impossible),
|
||||
ClientState::Registered | ClientState::Spectator | ClientState::Character
|
||||
=> new_chat_msgs.push((entity, msg)),
|
||||
ClientState::Registered
|
||||
| ClientState::Spectator
|
||||
| ClientState::Character => new_chat_msgs.push((entity, msg)),
|
||||
},
|
||||
ClientMsg::PlayerAnimation(animation_history) => match client.client_state {
|
||||
ClientState::Character => state.write_component(entity, animation_history),
|
||||
// Only characters can send animations
|
||||
_ => client.error_state(RequestStateError::Impossible),
|
||||
},
|
||||
}
|
||||
ClientMsg::PlayerPhysics { pos, vel, dir } => match client.client_state {
|
||||
ClientState::Character => {
|
||||
state.write_component(entity, pos);
|
||||
state.write_component(entity, vel);
|
||||
state.write_component(entity, dir);
|
||||
},
|
||||
}
|
||||
// Only characters send their position
|
||||
_ => client.error_state(RequestStateError::Impossible),
|
||||
},
|
||||
@ -323,11 +328,11 @@ impl Server {
|
||||
}),*/
|
||||
None => requested_chunks.push(key),
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
// Always possible
|
||||
ClientMsg::Ping => client.postbox.send_message(ServerMsg::Pong),
|
||||
ClientMsg::Pong => {},
|
||||
ClientMsg::Pong => {}
|
||||
ClientMsg::Disconnect => disconnect = true,
|
||||
}
|
||||
}
|
||||
@ -343,8 +348,10 @@ impl Server {
|
||||
|
||||
if disconnect {
|
||||
disconnected_clients.push(entity);
|
||||
client.postbox.send_message(ServerMsg::StateAnswer(
|
||||
Err((RequestStateError::Impossible, ClientState::Connected))));
|
||||
client.postbox.send_message(ServerMsg::StateAnswer(Err((
|
||||
RequestStateError::Impossible,
|
||||
ClientState::Connected,
|
||||
))));
|
||||
true
|
||||
} else {
|
||||
false
|
||||
@ -359,12 +366,7 @@ impl Server {
|
||||
self.process_chat_cmd(entity, argv);
|
||||
} else {
|
||||
self.clients.notify_registered(ServerMsg::Chat(
|
||||
match self
|
||||
.state
|
||||
.ecs()
|
||||
.read_storage::<comp::Player>()
|
||||
.get(entity)
|
||||
{
|
||||
match self.state.ecs().read_storage::<comp::Player>().get(entity) {
|
||||
Some(player) => format!("[{}] {}", &player.alias, msg),
|
||||
None => format!("[<anon>] {}", msg),
|
||||
},
|
||||
@ -404,7 +406,9 @@ impl Server {
|
||||
&state.ecs().entities(),
|
||||
&state.ecs().read_storage::<common::state::Uid>(),
|
||||
&state.ecs().read_storage::<comp::AnimationHistory>(),
|
||||
).join() {
|
||||
)
|
||||
.join()
|
||||
{
|
||||
// AnimationHistory
|
||||
client.postbox.send_message(ServerMsg::EntityAnimation {
|
||||
entity: uid.into(),
|
||||
@ -419,7 +423,8 @@ impl Server {
|
||||
/// Sync client states with the most up to date information
|
||||
fn sync_clients(&mut self) {
|
||||
// Sync 'logical' state using Sphynx
|
||||
self.clients.notify_registered(ServerMsg::EcsSync(self.state.ecs_mut().next_sync_package()));
|
||||
self.clients
|
||||
.notify_registered(ServerMsg::EcsSync(self.state.ecs_mut().next_sync_package()));
|
||||
|
||||
// Sync 'physical' state
|
||||
for (entity, &uid, &pos, &vel, &dir, force_update) in (
|
||||
@ -429,7 +434,9 @@ impl Server {
|
||||
&self.state.ecs().read_storage::<comp::phys::Vel>(),
|
||||
&self.state.ecs().read_storage::<comp::phys::Dir>(),
|
||||
self.state.ecs().read_storage::<comp::phys::ForceUpdate>().maybe(),
|
||||
).join() {
|
||||
)
|
||||
.join()
|
||||
{
|
||||
let msg = ServerMsg::EntityPhysics {
|
||||
entity: uid.into(),
|
||||
pos,
|
||||
@ -448,23 +455,30 @@ impl Server {
|
||||
&self.state.ecs().entities(),
|
||||
&self.state.ecs().read_storage::<Uid>(),
|
||||
&self.state.ecs().read_storage::<comp::AnimationHistory>(),
|
||||
).join() {
|
||||
)
|
||||
.join()
|
||||
{
|
||||
// Check if we need to sync
|
||||
if Some(animation_history.current) == animation_history.last {
|
||||
continue;
|
||||
}
|
||||
|
||||
self.clients.notify_ingame_except(entity, ServerMsg::EntityAnimation {
|
||||
self.clients.notify_ingame_except(
|
||||
entity,
|
||||
ServerMsg::EntityAnimation {
|
||||
entity: uid.into(),
|
||||
animation_history,
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
// Update animation last/current state
|
||||
for (entity, mut animation_history) in (
|
||||
&self.state.ecs().entities(),
|
||||
&mut self.state.ecs().write_storage::<comp::AnimationHistory>()
|
||||
).join() {
|
||||
&mut self.state.ecs().write_storage::<comp::AnimationHistory>(),
|
||||
)
|
||||
.join()
|
||||
{
|
||||
animation_history.last = Some(animation_history.current);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user