mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Started work on server-side chunks
Former-commit-id: 84a6bd7358f67a77043c4b11c787538f073c8d28
This commit is contained in:
parent
11630877e3
commit
3d9f8105e6
@ -6,7 +6,6 @@ edition = "2018"
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
common = { package = "veloren-common", path = "../common" }
|
common = { package = "veloren-common", path = "../common" }
|
||||||
world = { package = "veloren-world", path = "../world" }
|
|
||||||
|
|
||||||
specs = "0.14"
|
specs = "0.14"
|
||||||
vek = "0.9"
|
vek = "0.9"
|
||||||
|
@ -15,7 +15,7 @@ use std::{
|
|||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use threadpool;
|
use threadpool::ThreadPool;
|
||||||
use specs::Builder;
|
use specs::Builder;
|
||||||
use common::{
|
use common::{
|
||||||
comp,
|
comp,
|
||||||
@ -24,7 +24,6 @@ use common::{
|
|||||||
net::PostBox,
|
net::PostBox,
|
||||||
msg::{ClientMsg, ServerMsg},
|
msg::{ClientMsg, ServerMsg},
|
||||||
};
|
};
|
||||||
use world::World;
|
|
||||||
|
|
||||||
const SERVER_TIMEOUT: f64 = 5.0; // Seconds
|
const SERVER_TIMEOUT: f64 = 5.0; // Seconds
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ pub enum Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
thread_pool: threadpool::ThreadPool,
|
thread_pool: ThreadPool,
|
||||||
|
|
||||||
last_ping: f64,
|
last_ping: f64,
|
||||||
postbox: PostBox<ClientMsg, ServerMsg>,
|
postbox: PostBox<ClientMsg, ServerMsg>,
|
||||||
@ -41,10 +40,7 @@ pub struct Client {
|
|||||||
tick: u64,
|
tick: u64,
|
||||||
state: State,
|
state: State,
|
||||||
player: Option<EcsEntity>,
|
player: Option<EcsEntity>,
|
||||||
|
view_distance: u64,
|
||||||
// Testing
|
|
||||||
world: World,
|
|
||||||
pub chunk: Option<TerrainChunk>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Client {
|
impl Client {
|
||||||
@ -54,6 +50,7 @@ impl Client {
|
|||||||
addr: A,
|
addr: A,
|
||||||
player: comp::Player,
|
player: comp::Player,
|
||||||
character: Option<comp::Character>,
|
character: Option<comp::Character>,
|
||||||
|
view_distance: u64,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
|
|
||||||
let mut postbox = PostBox::to_server(addr)?;
|
let mut postbox = PostBox::to_server(addr)?;
|
||||||
@ -85,10 +82,7 @@ impl Client {
|
|||||||
tick: 0,
|
tick: 0,
|
||||||
state,
|
state,
|
||||||
player,
|
player,
|
||||||
|
view_distance,
|
||||||
// Testing
|
|
||||||
world: World::new(),
|
|
||||||
chunk: None,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,6 +198,7 @@ impl Client {
|
|||||||
ServerMsg::Chat(msg) => frontend_events.push(Event::Chat(msg)),
|
ServerMsg::Chat(msg) => frontend_events.push(Event::Chat(msg)),
|
||||||
ServerMsg::SetPlayerEntity(uid) => self.player = Some(self.state.ecs().entity_from_uid(uid).unwrap()), // TODO: Don't unwrap here!
|
ServerMsg::SetPlayerEntity(uid) => self.player = Some(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),
|
ServerMsg::EcsSync(sync_package) => self.state.ecs_mut().sync_with_package(sync_package),
|
||||||
|
ServerMsg::TerrainChunkUpdate { key, chunk } => self.state.insert_chunk(key, chunk),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let Some(err) = self.postbox.error() {
|
} else if let Some(err) = self.postbox.error() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::comp;
|
use crate::comp;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub enum ClientMsg {
|
pub enum ClientMsg {
|
||||||
Connect {
|
Connect {
|
||||||
player: comp::Player,
|
player: comp::Player,
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
use vek::*;
|
||||||
|
use crate::terrain::TerrainChunk;
|
||||||
use super::EcsPacket;
|
use super::EcsPacket;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub enum ServerMsg {
|
pub enum ServerMsg {
|
||||||
Handshake {
|
Handshake {
|
||||||
ecs_state: sphynx::StatePackage<EcsPacket>,
|
ecs_state: sphynx::StatePackage<EcsPacket>,
|
||||||
@ -12,4 +14,8 @@ pub enum ServerMsg {
|
|||||||
Chat(String),
|
Chat(String),
|
||||||
SetPlayerEntity(u64),
|
SetPlayerEntity(u64),
|
||||||
EcsSync(sphynx::SyncPackage<EcsPacket>),
|
EcsSync(sphynx::SyncPackage<EcsPacket>),
|
||||||
|
TerrainChunkUpdate {
|
||||||
|
key: Vec3<i32>,
|
||||||
|
chunk: TerrainChunk,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ impl<T> From<mio_extras::channel::SendError<T>> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PostSend = 'static + serde::Serialize + Send + fmt::Debug;
|
pub trait PostSend = 'static + serde::Serialize + Send;
|
||||||
pub trait PostRecv = 'static + serde::de::DeserializeOwned + Send + fmt::Debug;
|
pub trait PostRecv = 'static + serde::de::DeserializeOwned + Send;
|
||||||
|
|
||||||
const TCP_TOK: Token = Token(0);
|
const TCP_TOK: Token = Token(0);
|
||||||
const CTRL_TOK: Token = Token(1);
|
const CTRL_TOK: Token = Token(1);
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
use std::time::Duration;
|
use std::{
|
||||||
|
time::Duration,
|
||||||
|
collections::HashSet,
|
||||||
|
};
|
||||||
use shred::{Fetch, FetchMut};
|
use shred::{Fetch, FetchMut};
|
||||||
use specs::{
|
use specs::{
|
||||||
Builder,
|
Builder,
|
||||||
@ -17,7 +20,10 @@ use vek::*;
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp,
|
comp,
|
||||||
sys,
|
sys,
|
||||||
terrain::TerrainMap,
|
terrain::{
|
||||||
|
TerrainMap,
|
||||||
|
TerrainChunk,
|
||||||
|
},
|
||||||
msg::EcsPacket,
|
msg::EcsPacket,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -36,17 +42,17 @@ struct Time(f64);
|
|||||||
pub struct DeltaTime(pub f64);
|
pub struct DeltaTime(pub f64);
|
||||||
|
|
||||||
pub struct Changes {
|
pub struct Changes {
|
||||||
pub new_chunks: Vec<Vec3<i32>>,
|
pub new_chunks: HashSet<Vec3<i32>>,
|
||||||
pub changed_chunks: Vec<Vec3<i32>>,
|
pub changed_chunks: HashSet<Vec3<i32>>,
|
||||||
pub removed_chunks: Vec<Vec3<i32>>,
|
pub removed_chunks: HashSet<Vec3<i32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Changes {
|
impl Changes {
|
||||||
pub fn default() -> Self {
|
pub fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
new_chunks: vec![],
|
new_chunks: HashSet::new(),
|
||||||
changed_chunks: vec![],
|
changed_chunks: HashSet::new(),
|
||||||
removed_chunks: vec![],
|
removed_chunks: HashSet::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,12 +158,23 @@ impl State {
|
|||||||
|
|
||||||
/// Get a reference to this state's terrain.
|
/// Get a reference to this state's terrain.
|
||||||
pub fn terrain(&self) -> Fetch<TerrainMap> {
|
pub fn terrain(&self) -> Fetch<TerrainMap> {
|
||||||
self.ecs.internal().read_resource::<TerrainMap>()
|
self.ecs
|
||||||
|
.internal()
|
||||||
|
.read_resource::<TerrainMap>()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Get rid of this since it shouldn't be needed
|
/// Insert the provided chunk into this state's terrain.
|
||||||
pub fn terrain_mut(&mut self) -> FetchMut<TerrainMap> {
|
pub fn insert_chunk(&mut self, key: Vec3<i32>, chunk: TerrainChunk) {
|
||||||
self.ecs.internal_mut().write_resource::<TerrainMap>()
|
if self.ecs
|
||||||
|
.internal_mut()
|
||||||
|
.write_resource::<TerrainMap>()
|
||||||
|
.insert(key, chunk)
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
self.changes.changed_chunks.insert(key);
|
||||||
|
} else {
|
||||||
|
self.changes.new_chunks.insert(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a single tick, simulating the game state by the given duration.
|
/// Execute a single tick, simulating the game state by the given duration.
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
use serde_derive::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub enum BiomeKind {
|
pub enum BiomeKind {
|
||||||
Void,
|
Void,
|
||||||
Grassland,
|
Grassland,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
// Library
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
use serde_derive::{Serialize, Deserialize};
|
||||||
|
|
||||||
// Crate
|
// Crate
|
||||||
use crate::vol::Vox;
|
use crate::vol::Vox;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
kind: u8,
|
kind: u8,
|
||||||
color: [u8; 3],
|
color: [u8; 3],
|
||||||
|
@ -7,10 +7,8 @@ pub use self::{
|
|||||||
biome::BiomeKind,
|
biome::BiomeKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Library
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
use serde_derive::{Serialize, Deserialize};
|
||||||
// Crate
|
|
||||||
use crate::{
|
use crate::{
|
||||||
vol::VolSize,
|
vol::VolSize,
|
||||||
volumes::{
|
volumes::{
|
||||||
@ -21,6 +19,7 @@ use crate::{
|
|||||||
|
|
||||||
// TerrainChunkSize
|
// TerrainChunkSize
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct TerrainChunkSize;
|
pub struct TerrainChunkSize;
|
||||||
|
|
||||||
impl VolSize for TerrainChunkSize {
|
impl VolSize for TerrainChunkSize {
|
||||||
@ -29,6 +28,7 @@ impl VolSize for TerrainChunkSize {
|
|||||||
|
|
||||||
// TerrainChunkMeta
|
// TerrainChunkMeta
|
||||||
|
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct TerrainChunkMeta {
|
pub struct TerrainChunkMeta {
|
||||||
biome: BiomeKind,
|
biome: BiomeKind,
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use std::marker::PhantomData;
|
|||||||
|
|
||||||
// Library
|
// Library
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
use serde_derive::{Serialize, Deserialize};
|
||||||
|
|
||||||
// Local
|
// Local
|
||||||
use crate::vol::{
|
use crate::vol::{
|
||||||
@ -23,6 +24,7 @@ pub enum ChunkErr {
|
|||||||
// V = Voxel
|
// V = Voxel
|
||||||
// S = Size (replace when const generics are a thing)
|
// S = Size (replace when const generics are a thing)
|
||||||
// M = Metadata
|
// M = Metadata
|
||||||
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
pub struct Chunk<V: Vox, S: VolSize, M> {
|
pub struct Chunk<V: Vox, S: VolSize, M> {
|
||||||
vox: Vec<V>,
|
vox: Vec<V>,
|
||||||
meta: M,
|
meta: M,
|
||||||
|
@ -129,4 +129,8 @@ impl<V: Vox, S: VolSize, M> VolMap<V, S, M> {
|
|||||||
pub fn remove(&mut self, key: &Vec3<i32>) -> Option<Chunk<V, S, M>> {
|
pub fn remove(&mut self, key: &Vec3<i32>) -> Option<Chunk<V, S, M>> {
|
||||||
self.chunks.remove(key)
|
self.chunks.remove(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn key_pos(&self, key: Vec3<i32>) -> Vec3<i32> {
|
||||||
|
key * S::SIZE.map(|e| e as i32)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,3 +10,4 @@ world = { package = "veloren-world", path = "../world" }
|
|||||||
|
|
||||||
specs = "0.14"
|
specs = "0.14"
|
||||||
vek = "0.9"
|
vek = "0.9"
|
||||||
|
threadpool = "1.7"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
use specs::Entity as EcsEntity;
|
use specs::Entity as EcsEntity;
|
||||||
use common::{
|
use common::{
|
||||||
comp,
|
comp,
|
||||||
@ -14,7 +15,6 @@ pub enum ClientState {
|
|||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
pub state: ClientState,
|
pub state: ClientState,
|
||||||
pub entity: EcsEntity,
|
|
||||||
pub postbox: PostBox<ServerMsg, ClientMsg>,
|
pub postbox: PostBox<ServerMsg, ClientMsg>,
|
||||||
pub last_ping: f64,
|
pub last_ping: f64,
|
||||||
}
|
}
|
||||||
@ -26,36 +26,42 @@ impl Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Clients {
|
pub struct Clients {
|
||||||
clients: Vec<Client>,
|
clients: HashMap<EcsEntity, Client>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Clients {
|
impl Clients {
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self {
|
Self {
|
||||||
clients: Vec::new(),
|
clients: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add(&mut self, client: Client) {
|
pub fn add(&mut self, entity: EcsEntity, client: Client) {
|
||||||
self.clients.push(client);
|
self.clients.insert(entity, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_if<F: FnMut(&mut Client) -> bool>(&mut self, f: F) {
|
pub fn remove_if<F: FnMut(EcsEntity, &mut Client) -> bool>(&mut self, mut f: F) {
|
||||||
self.clients.drain_filter(f);
|
self.clients.retain(|entity, client| !f(*entity, client));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn notify(&mut self, entity: EcsEntity, msg: ServerMsg) {
|
||||||
|
if let Some(client) = self.clients.get_mut(&entity) {
|
||||||
|
client.notify(msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn notify_connected(&mut self, msg: ServerMsg) {
|
pub fn notify_connected(&mut self, msg: ServerMsg) {
|
||||||
for client in &mut self.clients {
|
for client in self.clients.values_mut() {
|
||||||
if client.state == ClientState::Connected {
|
if client.state == ClientState::Connected {
|
||||||
client.postbox.send(msg.clone());
|
client.notify(msg.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn notify_connected_except(&mut self, entity: EcsEntity, msg: ServerMsg) {
|
pub fn notify_connected_except(&mut self, except_entity: EcsEntity, msg: ServerMsg) {
|
||||||
for client in &mut self.clients {
|
for (entity, client) in self.clients.iter_mut() {
|
||||||
if client.entity != entity && client.state == ClientState::Connected {
|
if client.state == ClientState::Connected && *entity != except_entity {
|
||||||
client.postbox.send(msg.clone());
|
client.notify(msg.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ pub use crate::{
|
|||||||
use std::{
|
use std::{
|
||||||
time::Duration,
|
time::Duration,
|
||||||
net::SocketAddr,
|
net::SocketAddr,
|
||||||
|
sync::mpsc,
|
||||||
};
|
};
|
||||||
use specs::{
|
use specs::{
|
||||||
Entity as EcsEntity,
|
Entity as EcsEntity,
|
||||||
@ -22,11 +23,13 @@ use specs::{
|
|||||||
saveload::MarkedBuilder,
|
saveload::MarkedBuilder,
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
use threadpool::ThreadPool;
|
||||||
use common::{
|
use common::{
|
||||||
comp,
|
comp,
|
||||||
state::State,
|
state::State,
|
||||||
net::PostOffice,
|
net::PostOffice,
|
||||||
msg::{ServerMsg, ClientMsg},
|
msg::{ServerMsg, ClientMsg},
|
||||||
|
terrain::TerrainChunk,
|
||||||
};
|
};
|
||||||
use world::World;
|
use world::World;
|
||||||
use crate::client::{
|
use crate::client::{
|
||||||
@ -56,18 +59,30 @@ pub struct Server {
|
|||||||
|
|
||||||
postoffice: PostOffice<ServerMsg, ClientMsg>,
|
postoffice: PostOffice<ServerMsg, ClientMsg>,
|
||||||
clients: Clients,
|
clients: Clients,
|
||||||
|
|
||||||
|
thread_pool: ThreadPool,
|
||||||
|
chunk_tx: mpsc::Sender<(Vec3<i32>, TerrainChunk)>,
|
||||||
|
chunk_rx: mpsc::Receiver<(Vec3<i32>, TerrainChunk)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
/// Create a new `Server`.
|
/// Create a new `Server`.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn new() -> Result<Self, Error> {
|
pub fn new() -> Result<Self, Error> {
|
||||||
|
let (chunk_tx, chunk_rx) = mpsc::channel();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
state: State::new(),
|
state: State::new(),
|
||||||
world: World::new(),
|
world: World::new(),
|
||||||
|
|
||||||
postoffice: PostOffice::bind(SocketAddr::from(([0; 4], 59003)))?,
|
postoffice: PostOffice::bind(SocketAddr::from(([0; 4], 59003)))?,
|
||||||
clients: Clients::empty(),
|
clients: Clients::empty(),
|
||||||
|
|
||||||
|
thread_pool: threadpool::Builder::new()
|
||||||
|
.thread_name("veloren-worker".into())
|
||||||
|
.build(),
|
||||||
|
chunk_tx,
|
||||||
|
chunk_rx,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,6 +134,27 @@ impl Server {
|
|||||||
// Tick the client's LocalState (step 3)
|
// Tick the client's LocalState (step 3)
|
||||||
self.state.tick(dt);
|
self.state.tick(dt);
|
||||||
|
|
||||||
|
// Fetch any generated `TerrainChunk`s and insert them into the terrain
|
||||||
|
// Also, send the chunk data to anybody that is close by
|
||||||
|
for (key, chunk) in self.chunk_rx.try_iter() {
|
||||||
|
// Send the chunk to all nearby players
|
||||||
|
for (entity, player, pos) in (
|
||||||
|
&self.state.ecs().internal().entities(),
|
||||||
|
&self.state.ecs().internal().read_storage::<comp::Player>(),
|
||||||
|
&self.state.ecs().internal().read_storage::<comp::phys::Pos>(),
|
||||||
|
).join() {
|
||||||
|
// TODO: Distance check
|
||||||
|
// if self.state.terrain().key_pos(key)
|
||||||
|
|
||||||
|
self.clients.notify(entity, ServerMsg::TerrainChunkUpdate {
|
||||||
|
key,
|
||||||
|
chunk: chunk.clone(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
self.state.insert_chunk(key, chunk);
|
||||||
|
}
|
||||||
|
|
||||||
// Synchronise clients with the new state of the world
|
// Synchronise clients with the new state of the world
|
||||||
self.sync_clients();
|
self.sync_clients();
|
||||||
|
|
||||||
@ -143,9 +179,8 @@ impl Server {
|
|||||||
.create_entity_synced()
|
.create_entity_synced()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
self.clients.add(Client {
|
self.clients.add(entity, Client {
|
||||||
state: ClientState::Connecting,
|
state: ClientState::Connecting,
|
||||||
entity,
|
|
||||||
postbox,
|
postbox,
|
||||||
last_ping: self.state.get_time(),
|
last_ping: self.state.get_time(),
|
||||||
});
|
});
|
||||||
@ -166,7 +201,7 @@ impl Server {
|
|||||||
let mut new_chat_msgs = Vec::new();
|
let mut new_chat_msgs = Vec::new();
|
||||||
let mut disconnected_clients = Vec::new();
|
let mut disconnected_clients = Vec::new();
|
||||||
|
|
||||||
self.clients.remove_if(|client| {
|
self.clients.remove_if(|entity, client| {
|
||||||
let mut disconnect = false;
|
let mut disconnect = false;
|
||||||
let new_msgs = client.postbox.new_messages();
|
let new_msgs = client.postbox.new_messages();
|
||||||
|
|
||||||
@ -181,12 +216,12 @@ impl Server {
|
|||||||
ClientMsg::Connect { player, character } => {
|
ClientMsg::Connect { player, character } => {
|
||||||
|
|
||||||
// Write client components
|
// Write client components
|
||||||
state.write_component(client.entity, player);
|
state.write_component(entity, player);
|
||||||
state.write_component(client.entity, comp::phys::Pos(Vec3::zero()));
|
state.write_component(entity, comp::phys::Pos(Vec3::zero()));
|
||||||
state.write_component(client.entity, comp::phys::Vel(Vec3::zero()));
|
state.write_component(entity, comp::phys::Vel(Vec3::zero()));
|
||||||
state.write_component(client.entity, comp::phys::Dir(Vec3::unit_y()));
|
state.write_component(entity, comp::phys::Dir(Vec3::unit_y()));
|
||||||
if let Some(character) = character {
|
if let Some(character) = character {
|
||||||
state.write_component(client.entity, character);
|
state.write_component(entity, character);
|
||||||
}
|
}
|
||||||
|
|
||||||
client.state = ClientState::Connected;
|
client.state = ClientState::Connected;
|
||||||
@ -196,7 +231,7 @@ impl Server {
|
|||||||
ecs_state: state.ecs().gen_state_package(),
|
ecs_state: state.ecs().gen_state_package(),
|
||||||
player_entity: state
|
player_entity: state
|
||||||
.ecs()
|
.ecs()
|
||||||
.uid_from_entity(client.entity)
|
.uid_from_entity(entity)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into(),
|
.into(),
|
||||||
});
|
});
|
||||||
@ -207,11 +242,11 @@ impl Server {
|
|||||||
ClientMsg::Connect { .. } => disconnect = true, // Not allowed when already connected
|
ClientMsg::Connect { .. } => disconnect = true, // Not allowed when already connected
|
||||||
ClientMsg::Ping => client.postbox.send(ServerMsg::Pong),
|
ClientMsg::Ping => client.postbox.send(ServerMsg::Pong),
|
||||||
ClientMsg::Pong => {},
|
ClientMsg::Pong => {},
|
||||||
ClientMsg::Chat(msg) => new_chat_msgs.push((client.entity, msg)),
|
ClientMsg::Chat(msg) => new_chat_msgs.push((entity, msg)),
|
||||||
ClientMsg::PlayerPhysics { pos, vel, dir } => {
|
ClientMsg::PlayerPhysics { pos, vel, dir } => {
|
||||||
state.write_component(client.entity, pos);
|
state.write_component(entity, pos);
|
||||||
state.write_component(client.entity, vel);
|
state.write_component(entity, vel);
|
||||||
state.write_component(client.entity, dir);
|
state.write_component(entity, dir);
|
||||||
},
|
},
|
||||||
ClientMsg::Disconnect => disconnect = true,
|
ClientMsg::Disconnect => disconnect = true,
|
||||||
},
|
},
|
||||||
@ -228,7 +263,7 @@ impl Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if disconnect {
|
if disconnect {
|
||||||
disconnected_clients.push(client.entity);
|
disconnected_clients.push(entity);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -58,7 +58,7 @@ impl PlayState for MainMenuState {
|
|||||||
|
|
||||||
global_state.window.renderer_mut().clear(BG_COLOR);
|
global_state.window.renderer_mut().clear(BG_COLOR);
|
||||||
|
|
||||||
// Maintain the UI
|
// Maintain the UI (TODO: Maybe clean this up a little to avoid rightward drift?)
|
||||||
for event in self.main_menu_ui.maintain(global_state.window.renderer_mut()) {
|
for event in self.main_menu_ui.maintain(global_state.window.renderer_mut()) {
|
||||||
match event {
|
match event {
|
||||||
MainMenuEvent::LoginAttempt{ username, server_address } => {
|
MainMenuEvent::LoginAttempt{ username, server_address } => {
|
||||||
@ -70,7 +70,7 @@ impl PlayState for MainMenuState {
|
|||||||
Ok(mut socket_adders) => {
|
Ok(mut socket_adders) => {
|
||||||
while let Some(socket_addr) = socket_adders.next() {
|
while let Some(socket_addr) = socket_adders.next() {
|
||||||
// TODO: handle error
|
// TODO: handle error
|
||||||
match Client::new(socket_addr, comp::Player::new(username.clone()), Some(comp::Character::test())) {
|
match Client::new(socket_addr, comp::Player::new(username.clone()), Some(comp::Character::test()), 300) {
|
||||||
Ok(client) => {
|
Ok(client) => {
|
||||||
return PlayStateResult::Push(
|
return PlayStateResult::Push(
|
||||||
Box::new(CharSelectionState::new(
|
Box::new(CharSelectionState::new(
|
||||||
|
Loading…
Reference in New Issue
Block a user