mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-25 16:28:42 -06:00
protocol id
This commit is contained in:
parent
a5b35ffa7d
commit
6b9243a556
|
@ -1,3 +1,4 @@
|
||||||
[server]
|
[server]
|
||||||
address = "0.0.0.0:12345"
|
address = "0.0.0.0:12345"
|
||||||
max_clients = 254
|
max_clients = 254
|
||||||
|
timeout_ms = 10000
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::{fs, net::SocketAddr};
|
||||||
pub struct ConfigTableServer {
|
pub struct ConfigTableServer {
|
||||||
pub address: SocketAddr,
|
pub address: SocketAddr,
|
||||||
pub max_clients: usize,
|
pub max_clients: usize,
|
||||||
|
pub timeout_ms: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Unique, Serialize, Deserialize)]
|
#[derive(Unique, Serialize, Deserialize)]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut};
|
use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut};
|
||||||
use kubi_udp::server::{Server, ServerConfig};
|
use kubi_udp::server::{Server, ServerConfig};
|
||||||
use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage};
|
use kubi_shared::networking::messages::{ClientToServerMessage, ServerToClientMessage};
|
||||||
|
use std::time::Duration;
|
||||||
use crate::config::ConfigTable;
|
use crate::config::ConfigTable;
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
|
@ -14,7 +15,11 @@ pub fn bind_server(
|
||||||
let config = storages.borrow::<UniqueView<ConfigTable>>().unwrap();
|
let config = storages.borrow::<UniqueView<ConfigTable>>().unwrap();
|
||||||
let server: Server<ServerToClientMessage, ClientToServerMessage> = Server::bind(
|
let server: Server<ServerToClientMessage, ClientToServerMessage> = Server::bind(
|
||||||
config.server.address,
|
config.server.address,
|
||||||
ServerConfig { max_clients: config.server.max_clients }
|
ServerConfig {
|
||||||
|
max_clients: config.server.max_clients,
|
||||||
|
client_timeout: Duration::from_millis(config.server.timeout_ms),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
).unwrap();
|
).unwrap();
|
||||||
storages.add_unique(UdpServer(server));
|
storages.add_unique(UdpServer(server));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,9 @@ type IVec3Arr = [i32; 3];
|
||||||
type Vec3Arr = [f32; 3];
|
type Vec3Arr = [f32; 3];
|
||||||
type QuatArr = [f32; 3];
|
type QuatArr = [f32; 3];
|
||||||
|
|
||||||
#[derive(Encode, Decode)]
|
pub const PROTOCOL_ID: u16 = 1;
|
||||||
|
|
||||||
|
#[derive(Encode, Decode, Clone)]
|
||||||
pub enum ClientToServerMessage {
|
pub enum ClientToServerMessage {
|
||||||
ClientHello {
|
ClientHello {
|
||||||
username: String,
|
username: String,
|
||||||
|
@ -21,7 +23,7 @@ pub enum ClientToServerMessage {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode)]
|
#[derive(Encode, Decode, Clone)]
|
||||||
pub enum ServerToClientMessage {
|
pub enum ServerToClientMessage {
|
||||||
ServerHello,
|
ServerHello,
|
||||||
ServerFuckOff {
|
ServerFuckOff {
|
||||||
|
|
|
@ -6,11 +6,10 @@ use std::{
|
||||||
collections::{VecDeque, vec_deque::Drain as DrainDeque},
|
collections::{VecDeque, vec_deque::Drain as DrainDeque},
|
||||||
io::ErrorKind,
|
io::ErrorKind,
|
||||||
};
|
};
|
||||||
use bincode::{Encode, Decode};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BINCODE_CONFIG,
|
BINCODE_CONFIG,
|
||||||
packet::{ClientPacket, IdClientPacket, IdServerPacket, ServerPacket},
|
packet::{ClientPacket, IdClientPacket, IdServerPacket, ServerPacket, Message},
|
||||||
common::ClientId
|
common::{ClientId, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID}
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug)]
|
#[derive(Default, Clone, Debug)]
|
||||||
|
@ -22,6 +21,7 @@ pub enum DisconnectReason {
|
||||||
KickedByServer(Option<String>),
|
KickedByServer(Option<String>),
|
||||||
Timeout,
|
Timeout,
|
||||||
ConnectionReset,
|
ConnectionReset,
|
||||||
|
InvalidProtocolId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
|
@ -33,25 +33,27 @@ pub enum ClientStatus {
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct ClientConfig {
|
pub struct ClientConfig {
|
||||||
|
pub protocol_id: u16,
|
||||||
pub timeout: Duration,
|
pub timeout: Duration,
|
||||||
pub heartbeat_interval: Duration,
|
pub heartbeat_interval: Duration,
|
||||||
}
|
}
|
||||||
impl Default for ClientConfig {
|
impl Default for ClientConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
protocol_id: DEFAULT_USER_PROTOCOL_ID,
|
||||||
timeout: Duration::from_secs(5),
|
timeout: Duration::from_secs(5),
|
||||||
heartbeat_interval: Duration::from_secs(3),
|
heartbeat_interval: Duration::from_secs(3),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ClientEvent<T> where T: Encode + Decode {
|
pub enum ClientEvent<T> where T: Message {
|
||||||
Connected(ClientId),
|
Connected(ClientId),
|
||||||
Disconnected(DisconnectReason),
|
Disconnected(DisconnectReason),
|
||||||
MessageReceived(T)
|
MessageReceived(T)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Client<S, R> where S: Encode + Decode, R: Encode + Decode {
|
pub struct Client<S, R> where S: Message, R: Message {
|
||||||
config: ClientConfig,
|
config: ClientConfig,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
socket: UdpSocket,
|
socket: UdpSocket,
|
||||||
|
@ -63,9 +65,15 @@ pub struct Client<S, R> where S: Encode + Decode, R: Encode + Decode {
|
||||||
event_queue: VecDeque<ClientEvent<R>>,
|
event_queue: VecDeque<ClientEvent<R>>,
|
||||||
_s: PhantomData<S>,
|
_s: PhantomData<S>,
|
||||||
}
|
}
|
||||||
impl<S, R> Client<S, R> where S: Encode + Decode, R: Encode + Decode {
|
impl<S, R> Client<S, R> where S: Message, R: Message {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(addr: SocketAddr, config: ClientConfig) -> Result<Self> {
|
pub fn new(addr: SocketAddr, config: ClientConfig) -> Result<Self> {
|
||||||
|
if config.protocol_id == 0 {
|
||||||
|
log::warn!("Warning: using 0 as protocol_id is not recommended");
|
||||||
|
}
|
||||||
|
if config.protocol_id == DEFAULT_USER_PROTOCOL_ID {
|
||||||
|
log::warn!("Warning: using default protocol_id is not recommended");
|
||||||
|
}
|
||||||
let bind_addr: SocketAddr = "0.0.0.0:0".parse().unwrap();
|
let bind_addr: SocketAddr = "0.0.0.0:0".parse().unwrap();
|
||||||
let socket = UdpSocket::bind(bind_addr)?;
|
let socket = UdpSocket::bind(bind_addr)?;
|
||||||
socket.set_nonblocking(true)?;
|
socket.set_nonblocking(true)?;
|
||||||
|
@ -107,7 +115,7 @@ impl<S, R> Client<S, R> where S: Encode + Decode, R: Encode + Decode {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn connect(&mut self) -> Result<()> {
|
pub fn connect(&mut self) -> Result<()> {
|
||||||
log::info!("client connect called");
|
log::info!("Client connecting..");
|
||||||
if self.status != ClientStatus::Disconnected {
|
if self.status != ClientStatus::Disconnected {
|
||||||
bail!("Not Disconnected");
|
bail!("Not Disconnected");
|
||||||
}
|
}
|
||||||
|
@ -115,7 +123,10 @@ impl<S, R> Client<S, R> where S: Encode + Decode, R: Encode + Decode {
|
||||||
self.last_heartbeat = Instant::now();
|
self.last_heartbeat = Instant::now();
|
||||||
self.reset_timeout();
|
self.reset_timeout();
|
||||||
self.socket.connect(self.addr)?;
|
self.socket.connect(self.addr)?;
|
||||||
self.send_raw_packet(ClientPacket::Connect)?;
|
self.send_raw_packet(ClientPacket::Connect{
|
||||||
|
user_protocol: self.config.protocol_id,
|
||||||
|
inner_protocol: PROTOCOL_ID,
|
||||||
|
})?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +227,15 @@ impl<S, R> Client<S, R> where S: Encode + Decode, R: Encode + Decode {
|
||||||
},
|
},
|
||||||
ServerPacket::Data(message) => {
|
ServerPacket::Data(message) => {
|
||||||
self.event_queue.push_back(ClientEvent::MessageReceived(message));
|
self.event_queue.push_back(ClientEvent::MessageReceived(message));
|
||||||
|
self.timeout = Instant::now();
|
||||||
|
},
|
||||||
|
ServerPacket::Heartbeat => {
|
||||||
|
self.timeout = Instant::now();
|
||||||
|
},
|
||||||
|
ServerPacket::ProtoDisconnect => {
|
||||||
|
let reason = DisconnectReason::InvalidProtocolId;
|
||||||
|
self.disconnect_inner(reason, true)?; //this should never fail but we're handling the error anyway
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,3 +3,6 @@ use std::num::NonZeroU8;
|
||||||
pub type ClientId = NonZeroU8;
|
pub type ClientId = NonZeroU8;
|
||||||
pub type ClientIdRepr = u8;
|
pub type ClientIdRepr = u8;
|
||||||
pub const MAX_CLIENTS: usize = u8::MAX as _;
|
pub const MAX_CLIENTS: usize = u8::MAX as _;
|
||||||
|
|
||||||
|
pub const PROTOCOL_ID: u16 = 1;
|
||||||
|
pub const DEFAULT_USER_PROTOCOL_ID: u16 = 0xcafe;
|
||||||
|
|
|
@ -1,25 +1,33 @@
|
||||||
use bincode::{Encode, Decode};
|
use bincode::{Encode, Decode};
|
||||||
use crate::common::ClientId;
|
use crate::common::ClientId;
|
||||||
|
|
||||||
|
pub trait Message: Encode + Decode + Clone {}
|
||||||
|
impl<T: Encode + Decode + Clone> Message for T {}
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(Encode, Decode)]
|
#[derive(Encode, Decode)]
|
||||||
pub enum ClientPacket<T> where T: Encode + Decode {
|
pub enum ClientPacket<T> where T: Message {
|
||||||
|
Connect {
|
||||||
|
inner_protocol: u16,
|
||||||
|
user_protocol: u16,
|
||||||
|
}, //should always stay 0!
|
||||||
Data(T),
|
Data(T),
|
||||||
Connect,
|
|
||||||
Disconnect,
|
Disconnect,
|
||||||
Heartbeat,
|
Heartbeat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode)]
|
#[derive(Encode, Decode)]
|
||||||
pub struct IdClientPacket<T: Encode + Decode>(pub Option<ClientId>, pub ClientPacket<T>);
|
pub struct IdClientPacket<T: Message>(pub Option<ClientId>, pub ClientPacket<T>);
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(Encode, Decode)]
|
#[derive(Encode, Decode)]
|
||||||
pub enum ServerPacket<T> where T: Encode + Decode {
|
pub enum ServerPacket<T> where T: Message {
|
||||||
|
ProtoDisconnect = 0,
|
||||||
Data(T),
|
Data(T),
|
||||||
Connected(ClientId),
|
|
||||||
Disconnected(String),
|
Disconnected(String),
|
||||||
|
Connected(ClientId),
|
||||||
|
Heartbeat,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Encode, Decode)]
|
#[derive(Encode, Decode)]
|
||||||
pub struct IdServerPacket<T: Encode + Decode>(pub Option<ClientId>, pub ServerPacket<T>);
|
pub struct IdServerPacket<T: Message>(pub Option<ClientId>, pub ServerPacket<T>);
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
use std::{
|
use std::{
|
||||||
net::{UdpSocket, SocketAddr},
|
net::{UdpSocket, SocketAddr},
|
||||||
time::Instant,
|
time::{Instant, Duration},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
collections::{VecDeque, vec_deque::Drain as DrainDeque},
|
collections::{VecDeque, vec_deque::Drain as DrainDeque},
|
||||||
io::ErrorKind
|
io::ErrorKind
|
||||||
};
|
};
|
||||||
use anyhow::{Result, bail};
|
use anyhow::{Result, bail};
|
||||||
use bincode::{Encode, Decode};
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use nohash_hasher::BuildNoHashHasher;
|
use nohash_hasher::BuildNoHashHasher;
|
||||||
use crate::{
|
use crate::{
|
||||||
BINCODE_CONFIG,
|
BINCODE_CONFIG,
|
||||||
common::{ClientId, ClientIdRepr, MAX_CLIENTS},
|
common::{ClientId, ClientIdRepr, MAX_CLIENTS, PROTOCOL_ID, DEFAULT_USER_PROTOCOL_ID},
|
||||||
packet::{IdClientPacket, ClientPacket, ServerPacket, IdServerPacket}
|
packet::{IdClientPacket, ClientPacket, ServerPacket, IdServerPacket, Message}
|
||||||
};
|
};
|
||||||
|
|
||||||
//i was feeling a bit sick while writing most of this please excuse me for my terrible code :3
|
//i was feeling a bit sick while writing most of this please excuse me for my terrible code :3
|
||||||
|
@ -26,16 +25,20 @@ pub struct ConnectedClient {
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct ServerConfig {
|
pub struct ServerConfig {
|
||||||
pub max_clients: usize,
|
pub max_clients: usize,
|
||||||
|
pub client_timeout: Duration,
|
||||||
|
pub protocol_id: u16,
|
||||||
}
|
}
|
||||||
impl Default for ServerConfig {
|
impl Default for ServerConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
max_clients: MAX_CLIENTS,
|
max_clients: MAX_CLIENTS,
|
||||||
|
client_timeout: Duration::from_secs(5),
|
||||||
|
protocol_id: DEFAULT_USER_PROTOCOL_ID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ServerEvent<T> where T: Encode + Decode {
|
pub enum ServerEvent<T> where T: Message {
|
||||||
Connected(ClientId),
|
Connected(ClientId),
|
||||||
Disconnected(ClientId),
|
Disconnected(ClientId),
|
||||||
MessageReceived {
|
MessageReceived {
|
||||||
|
@ -44,16 +47,22 @@ pub enum ServerEvent<T> where T: Encode + Decode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Server<S, R> where S: Encode + Decode, R: Encode + Decode {
|
pub struct Server<S, R> where S: Message, R: Message {
|
||||||
socket: UdpSocket,
|
socket: UdpSocket,
|
||||||
clients: HashMap<ClientId, ConnectedClient, BuildNoHashHasher<ClientIdRepr>>,
|
clients: HashMap<ClientId, ConnectedClient, BuildNoHashHasher<ClientIdRepr>>,
|
||||||
config: ServerConfig,
|
config: ServerConfig,
|
||||||
event_queue: VecDeque<ServerEvent<R>>,
|
event_queue: VecDeque<ServerEvent<R>>,
|
||||||
_s: PhantomData<S>,
|
_s: PhantomData<S>,
|
||||||
}
|
}
|
||||||
impl<S, R> Server<S, R> where S: Encode + Decode, R: Encode + Decode {
|
impl<S, R> Server<S, R> where S: Message, R: Message {
|
||||||
pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result<Self> {
|
pub fn bind(addr: SocketAddr, config: ServerConfig) -> anyhow::Result<Self> {
|
||||||
assert!(config.max_clients <= MAX_CLIENTS);
|
assert!(config.max_clients <= MAX_CLIENTS, "max_clients value exceeds the maximum allowed amount of clients");
|
||||||
|
if config.protocol_id == 0 {
|
||||||
|
log::warn!("Warning: using 0 as protocol_id is not recommended");
|
||||||
|
}
|
||||||
|
if config.protocol_id == DEFAULT_USER_PROTOCOL_ID {
|
||||||
|
log::warn!("Warning: using default protocol_id is not recommended");
|
||||||
|
}
|
||||||
let socket = UdpSocket::bind(addr)?;
|
let socket = UdpSocket::bind(addr)?;
|
||||||
socket.set_nonblocking(true)?;
|
socket.set_nonblocking(true)?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
@ -127,6 +136,12 @@ impl<S, R> Server<S, R> where S: Encode + Decode, R: Encode + Decode {
|
||||||
self.send_packet(IdServerPacket(Some(id), ServerPacket::Data(message)))?;
|
self.send_packet(IdServerPacket(Some(id), ServerPacket::Data(message)))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
pub fn multicast_message(&mut self, _clients: impl IntoIterator<Item = ClientId>, _message: S) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
pub fn broadcast_message(&mut self, _message: S) -> anyhow::Result<()> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update(&mut self) -> Result<()> {
|
pub fn update(&mut self) -> Result<()> {
|
||||||
//TODO client timeout
|
//TODO client timeout
|
||||||
|
@ -141,7 +156,10 @@ impl<S, R> Server<S, R> where S: Encode + Decode, R: Encode + Decode {
|
||||||
Some(id) => {
|
Some(id) => {
|
||||||
if !self.clients.contains_key(&id) {
|
if !self.clients.contains_key(&id) {
|
||||||
bail!("Client with id {id} doesn't exist");
|
bail!("Client with id {id} doesn't exist");
|
||||||
};
|
}
|
||||||
|
if self.clients.get(&id).unwrap().addr != addr {
|
||||||
|
bail!("Client addr doesn't match");
|
||||||
|
}
|
||||||
match packet {
|
match packet {
|
||||||
ClientPacket::Data(data) => {
|
ClientPacket::Data(data) => {
|
||||||
self.event_queue.push_back(ServerEvent::MessageReceived {
|
self.event_queue.push_back(ServerEvent::MessageReceived {
|
||||||
|
@ -155,21 +173,30 @@ impl<S, R> Server<S, R> where S: Encode + Decode, R: Encode + Decode {
|
||||||
self.disconnect_client_inner(id, "Disconnected".into())?;
|
self.disconnect_client_inner(id, "Disconnected".into())?;
|
||||||
},
|
},
|
||||||
ClientPacket::Heartbeat => {
|
ClientPacket::Heartbeat => {
|
||||||
self.clients.get_mut(&id).unwrap().timeout = Instant::now()
|
self.clients.get_mut(&id).unwrap().timeout = Instant::now();
|
||||||
|
self.send_packet(IdServerPacket(Some(id), ServerPacket::Heartbeat))?;
|
||||||
},
|
},
|
||||||
ClientPacket::Connect => bail!("Client already connected"),
|
ClientPacket::Connect{..} => bail!("Client already connected"),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
match packet {
|
match packet {
|
||||||
ClientPacket::Connect => {
|
ClientPacket::Connect { user_protocol, inner_protocol } => {
|
||||||
|
if (inner_protocol != PROTOCOL_ID) || (user_protocol != self.config.protocol_id ) {
|
||||||
|
log::error!("Client conenction refused: Invalid protocol id");
|
||||||
|
self.send_to_addr(addr,
|
||||||
|
IdServerPacket(None, ServerPacket::ProtoDisconnect)
|
||||||
|
)?;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
match self.add_client(addr) {
|
match self.add_client(addr) {
|
||||||
Ok(id) => {
|
Ok(id) => {
|
||||||
log::info!("Client with id {id} connected");
|
log::info!("Client with id {id} connected");
|
||||||
self.event_queue.push_back(ServerEvent::Connected(id));
|
self.event_queue.push_back(ServerEvent::Connected(id));
|
||||||
self.send_to_addr(addr,
|
self.send_to_addr(addr,
|
||||||
IdServerPacket(None, ServerPacket::Connected(id)
|
IdServerPacket(None, ServerPacket::Connected(id))
|
||||||
))?;
|
)?;
|
||||||
},
|
},
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
let reason = error.to_string();
|
let reason = error.to_string();
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, AllStoragesViewMut, View, UniqueView, NonSendSync, UniqueViewMut, IntoIter};
|
use shipyard::{Component, Unique, Workload, IntoWorkload, AllStoragesView, View, UniqueViewMut, IntoIter};
|
||||||
use glam::{Vec4, Mat3, vec2, Mat4};
|
use glam::{Vec4, Mat4};
|
||||||
use crate::{color::color_hex, transform::Transform2d, events::WindowResizedEvent, rendering::Renderer};
|
use crate::{color::color_hex, events::WindowResizedEvent};
|
||||||
|
|
||||||
pub mod text_widget;
|
pub mod text_widget;
|
||||||
pub mod progressbar;
|
pub mod progressbar;
|
||||||
|
|
||||||
use progressbar::{render_progressbars, ProgressbarComponent};
|
use progressbar::render_progressbars;
|
||||||
|
|
||||||
//TODO compute gui scale on window resize
|
//TODO compute gui scale on window resize
|
||||||
#[derive(Unique, Clone, Copy, Debug, Default)]
|
#[derive(Unique, Clone, Copy, Debug, Default)]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use shipyard::{AllStoragesViewMut, UniqueViewMut};
|
use shipyard::{AllStoragesViewMut, UniqueViewMut};
|
||||||
use std::{env, net::SocketAddr, borrow::BorrowMut};
|
use std::{env, net::SocketAddr};
|
||||||
use crate::{
|
use crate::{
|
||||||
networking::{GameType, ServerAddress},
|
networking::{GameType, ServerAddress},
|
||||||
state::{GameState, NextState}
|
state::{GameState, NextState}
|
||||||
|
|
|
@ -47,7 +47,7 @@ fn update_progress_bar_progress (
|
||||||
) {
|
) {
|
||||||
let bar = (&mut bar).get(eid.0).unwrap();
|
let bar = (&mut bar).get(eid.0).unwrap();
|
||||||
let loaded = world.chunks.iter().fold(0, |acc, (&_, chunk)| {
|
let loaded = world.chunks.iter().fold(0, |acc, (&_, chunk)| {
|
||||||
acc + chunk.desired_state.matches(chunk.current_state) as usize
|
acc + chunk.desired_state.matches_current(chunk.current_state) as usize
|
||||||
});
|
});
|
||||||
let total = world.chunks.len();
|
let total = world.chunks.len();
|
||||||
let progress = loaded as f32 / total as f32;
|
let progress = loaded as f32 / total as f32;
|
||||||
|
@ -62,7 +62,7 @@ fn switch_to_ingame_if_loaded(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if world.chunks.iter().all(|(_, chunk)| {
|
if world.chunks.iter().all(|(_, chunk)| {
|
||||||
chunk.desired_state.matches(chunk.current_state)
|
chunk.desired_state.matches_current(chunk.current_state)
|
||||||
}) {
|
}) {
|
||||||
log::info!("Finished loading chunks");
|
log::info!("Finished loading chunks");
|
||||||
state.0 = Some(GameState::InGame);
|
state.0 = Some(GameState::InGame);
|
||||||
|
|
|
@ -30,11 +30,6 @@ pub enum CurrentChunkState {
|
||||||
RecalculatingMesh,
|
RecalculatingMesh,
|
||||||
Unloading,
|
Unloading,
|
||||||
}
|
}
|
||||||
impl CurrentChunkState {
|
|
||||||
pub fn matches(self, desired: DesiredChunkState) -> bool {
|
|
||||||
desired.matches(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
|
||||||
pub enum DesiredChunkState {
|
pub enum DesiredChunkState {
|
||||||
|
@ -45,7 +40,7 @@ pub enum DesiredChunkState {
|
||||||
ToUnload,
|
ToUnload,
|
||||||
}
|
}
|
||||||
impl DesiredChunkState {
|
impl DesiredChunkState {
|
||||||
pub fn matches(self, current: CurrentChunkState) -> bool {
|
pub fn matches_current(self, current: CurrentChunkState) -> bool {
|
||||||
(matches!(self, DesiredChunkState::Nothing) && matches!(current, CurrentChunkState::Nothing)) ||
|
(matches!(self, DesiredChunkState::Nothing) && matches!(current, CurrentChunkState::Nothing)) ||
|
||||||
(matches!(self, DesiredChunkState::Loaded) && matches!(current, CurrentChunkState::Loaded)) ||
|
(matches!(self, DesiredChunkState::Loaded) && matches!(current, CurrentChunkState::Loaded)) ||
|
||||||
(matches!(self, DesiredChunkState::Rendered) && matches!(current, CurrentChunkState::Rendered))
|
(matches!(self, DesiredChunkState::Rendered) && matches!(current, CurrentChunkState::Rendered))
|
||||||
|
|
Loading…
Reference in a new issue