Compare commits

...

3 commits

Author SHA1 Message Date
griffi-gh 9f5b974f82 increase small 2024-02-01 16:21:10 +01:00
griffi-gh bfdd506ae8 rename guiv2_integration -> kubi_ui_integration 2024-02-01 16:12:51 +01:00
griffi-gh 3a42c293dd refactor net code to use enums 2024-02-01 16:00:32 +01:00
12 changed files with 136 additions and 88 deletions

View file

@ -8,10 +8,10 @@ use kubi_shared::{
ServerToClientMessage, ServerToClientMessage,
InitData, InitData,
ClientInitData, ClientInitData,
C_CLIENT_HELLO, ClientToServerMessageType,
}, },
client::{Client, ClientId, Username}, client::{Client, ClientId, Username},
channels::{CHANNEL_AUTH, CHANNEL_SYS_EVT}, channels::Channel,
}, },
player::{Player, PLAYER_HEALTH}, player::{Player, PLAYER_HEALTH},
transform::Transform, entity::{Entity, Health} transform::Transform, entity::{Entity, Health}
@ -37,7 +37,7 @@ pub fn authenticate_players(
let ServerEvent::Receive(client_addr, data) = event else{ let ServerEvent::Receive(client_addr, data) = event else{
continue continue
}; };
if !event.is_message_of_type::<C_CLIENT_HELLO>() { if !event.is_message_of_type::<{ClientToServerMessageType::ClientHello as u8}>() {
continue continue
} }
let Some(client) = server.0.client(client_addr) else { let Some(client) = server.0.client(client_addr) else {
@ -62,7 +62,7 @@ pub fn authenticate_players(
postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff {
reason: "Incorrect password".into() reason: "Incorrect password".into()
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );
continue continue
@ -72,7 +72,7 @@ pub fn authenticate_players(
postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff {
reason: "This server is password protected".into() reason: "This server is password protected".into()
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );
continue continue
@ -88,7 +88,7 @@ pub fn authenticate_players(
postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff { postcard::to_allocvec(&ServerToClientMessage::ServerFuckOff {
reason: "Can't find a free spot for you!".into() reason: "Can't find a free spot for you!".into()
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );
continue continue
@ -164,7 +164,7 @@ pub fn authenticate_players(
}; };
other_client.borrow_mut().send( other_client.borrow_mut().send(
postcard::to_allocvec(&message).unwrap().into_boxed_slice(), postcard::to_allocvec(&message).unwrap().into_boxed_slice(),
CHANNEL_SYS_EVT, Channel::SysEvt as usize,
SendMode::Reliable SendMode::Reliable
); );
} }
@ -175,7 +175,7 @@ pub fn authenticate_players(
postcard::to_allocvec(&ServerToClientMessage::ServerHello { postcard::to_allocvec(&ServerToClientMessage::ServerHello {
init: init_data init: init_data
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );

View file

@ -5,14 +5,14 @@ use uflow::SendMode;
use std::net::SocketAddr; use std::net::SocketAddr;
use kubi_shared::{ use kubi_shared::{
networking::{ networking::{
client::{ClientIdMap, Client}, client::{ClientIdMap, Client},
messages::{ClientToServerMessage, ServerToClientMessage, C_POSITION_CHANGED}, messages::{ClientToServerMessage, ServerToClientMessage, ClientToServerMessageType},
channels::CHANNEL_MOVE channels::Channel
}, },
transform::Transform transform::Transform
}; };
use crate::{ use crate::{
server::{ServerEvents, UdpServer}, server::{ServerEvents, UdpServer},
util::check_message_auth util::check_message_auth
}; };
@ -41,9 +41,10 @@ pub fn sync_client_positions(
addrs: View<ClientAddress>, addrs: View<ClientAddress>,
) { ) {
for event in &events.0 { for event in &events.0 {
let Some(message) = check_message_auth::<C_POSITION_CHANGED>(&server, event, &clients, &addr_map) else { let Some(message) = check_message_auth
continue; ::<{ClientToServerMessageType::PositionChanged as u8}>
}; (&server, event, &clients, &addr_map) else { continue };
let ClientToServerMessage::PositionChanged { position, velocity: _, direction } = message.message else { let ClientToServerMessage::PositionChanged { position, velocity: _, direction } = message.message else {
unreachable!() unreachable!()
}; };
@ -71,8 +72,8 @@ pub fn sync_client_positions(
position, position,
direction direction
} }
).unwrap().into_boxed_slice(), ).unwrap().into_boxed_slice(),
CHANNEL_MOVE, Channel::Move as usize,
SendMode::Reliable SendMode::Reliable
); );
} }

View file

@ -2,8 +2,8 @@ use shipyard::{Unique, UniqueView, UniqueViewMut, Workload, IntoWorkload, AllSto
use glam::IVec3; use glam::IVec3;
use hashbrown::HashMap; use hashbrown::HashMap;
use kubi_shared::networking::{ use kubi_shared::networking::{
messages::{ClientToServerMessage, ServerToClientMessage, C_CHUNK_SUB_REQUEST, C_QUEUE_BLOCK}, messages::{ClientToServerMessage, ServerToClientMessage, ClientToServerMessageType},
channels::{CHANNEL_WORLD, CHANNEL_BLOCK}, channels::Channel,
client::Client, client::Client,
}; };
use uflow::{server::RemoteClient, SendMode}; use uflow::{server::RemoteClient, SendMode};
@ -45,7 +45,11 @@ pub fn send_chunk_compressed(
ser_message.truncate(1); ser_message.truncate(1);
ser_message.append(&mut compressed); ser_message.append(&mut compressed);
let ser_message = ser_message.into_boxed_slice(); let ser_message = ser_message.into_boxed_slice();
client.borrow_mut().send(ser_message, CHANNEL_WORLD, SendMode::Reliable); client.borrow_mut().send(
ser_message,
Channel::World as usize,
SendMode::Reliable
);
Ok(()) Ok(())
} }
@ -59,9 +63,10 @@ fn process_chunk_requests(
clients: View<Client> clients: View<Client>
) { ) {
for event in &events.0 { for event in &events.0 {
let Some(message) = check_message_auth::<C_CHUNK_SUB_REQUEST>(&server, event, &clients, &addr_map) else { let Some(message) = check_message_auth
continue; ::<{ClientToServerMessageType::ChunkSubRequest as u8}>
}; (&server, event, &clients, &addr_map) else { continue };
let ClientToServerMessage::ChunkSubRequest { chunk: chunk_position } = message.message else { let ClientToServerMessage::ChunkSubRequest { chunk: chunk_position } = message.message else {
unreachable!() unreachable!()
}; };
@ -151,16 +156,17 @@ fn process_block_queue_messages(
addrs: View<ClientAddress>, addrs: View<ClientAddress>,
) { ) {
for event in &events.0 { for event in &events.0 {
let Some(message) = check_message_auth::<C_QUEUE_BLOCK>(&server, event, &clients, &addr_map) else { let Some(message) = check_message_auth
continue; ::<{ClientToServerMessageType::QueueBlock as u8}>
}; (&server, event, &clients, &addr_map) else { continue };
let ClientToServerMessage::QueueBlock { item } = message.message else { unreachable!() }; let ClientToServerMessage::QueueBlock { item } = message.message else { unreachable!() };
//TODO place in our own queue, for now just send to other clients //TODO place in our own queue, for now just send to other clients
log::info!("Placed block {:?} at {}", item.block_type, item.position); log::info!("Placed block {:?} at {}", item.block_type, item.position);
for (other_client, other_client_address) in (&clients, &addrs).iter() { for (other_client, other_client_address) in (&clients, &addrs).iter() {
//No need to send the event back //No need to send the event back
if message.client_id == other_client.0 { if message.client_id == other_client.0 {
continue continue
} }
//Get client //Get client
let Some(client) = server.0.client(&other_client_address.0) else { let Some(client) = server.0.client(&other_client_address.0) else {
@ -172,7 +178,7 @@ fn process_block_queue_messages(
postcard::to_allocvec( postcard::to_allocvec(
&ServerToClientMessage::QueueBlock { item } &ServerToClientMessage::QueueBlock { item }
).unwrap().into_boxed_slice(), ).unwrap().into_boxed_slice(),
CHANNEL_BLOCK, Channel::Block as usize,
SendMode::Reliable, SendMode::Reliable,
); );
} }

View file

@ -1,6 +1,9 @@
pub const CHANNEL_GENERIC: usize = 0; #[repr(u8)]
pub const CHANNEL_AUTH: usize = 1; pub enum Channel {
pub const CHANNEL_WORLD: usize = 2; Generic = 0,
pub const CHANNEL_BLOCK: usize = 3; Auth = 1,
pub const CHANNEL_MOVE: usize = 4; World = 2,
pub const CHANNEL_SYS_EVT: usize = 5; Block = 3,
Move = 4,
SysEvt = 5,
}

View file

@ -5,60 +5,86 @@ use super::client::ClientId;
pub const PROTOCOL_ID: u16 = 0; pub const PROTOCOL_ID: u16 = 0;
pub const C_CLIENT_HELLO: u8 = 0; pub trait ToMessageType<T> {
pub const C_POSITION_CHANGED: u8 = 1; fn message_type(&self) -> T;
pub const C_CHUNK_SUB_REQUEST: u8 = 2; }
pub const C_CHUNK_UNUBSCRIBE: u8 = 3;
pub const C_QUEUE_BLOCK: u8 = 4; #[repr(u8)]
#[non_exhaustive]
pub enum ClientToServerMessageType {
ClientHello = 0,
PositionChanged = 1,
ChunkSubRequest = 2,
ChunkUnsubscribe = 3,
QueueBlock = 4,
}
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
#[repr(u8)] #[repr(u8)]
#[non_exhaustive]
pub enum ClientToServerMessage { pub enum ClientToServerMessage {
ClientHello { ClientHello {
username: String, username: String,
password: Option<String>, password: Option<String>,
} = C_CLIENT_HELLO, } = ClientToServerMessageType::ClientHello as u8,
PositionChanged { PositionChanged {
position: Vec3, position: Vec3,
velocity: Vec3, velocity: Vec3,
direction: Quat, direction: Quat,
} = C_POSITION_CHANGED, } = ClientToServerMessageType::PositionChanged as u8,
ChunkSubRequest { ChunkSubRequest {
chunk: IVec3, chunk: IVec3,
} = C_CHUNK_SUB_REQUEST, } = ClientToServerMessageType::ChunkSubRequest as u8,
ChunkUnsubscribe { ChunkUnsubscribe {
chunk: IVec3, chunk: IVec3,
} = C_CHUNK_UNUBSCRIBE, } = ClientToServerMessageType::ChunkUnsubscribe as u8,
QueueBlock { QueueBlock {
item: QueuedBlock item: QueuedBlock
} = C_QUEUE_BLOCK, } = ClientToServerMessageType::QueueBlock as u8,
} }
pub const S_SERVER_HELLO: u8 = 0; impl ToMessageType<ClientToServerMessageType> for ClientToServerMessage {
pub const S_SERVER_FUCK_OFF: u8 = 1; fn message_type(&self) -> ClientToServerMessageType {
pub const S_PLAYER_POSITION_CHANGED: u8 = 2; match self {
pub const S_CHUNK_RESPONSE: u8 = 3; ClientToServerMessage::ClientHello { .. } => ClientToServerMessageType::ClientHello,
pub const S_QUEUE_BLOCK: u8 = 4; ClientToServerMessage::PositionChanged { .. } => ClientToServerMessageType::PositionChanged,
pub const S_PLAYER_CONNECTED: u8 = 5; ClientToServerMessage::ChunkSubRequest { .. } => ClientToServerMessageType::ChunkSubRequest,
pub const S_PLAYER_DISCONNECTED: u8 = 6; ClientToServerMessage::ChunkUnsubscribe { .. } => ClientToServerMessageType::ChunkUnsubscribe,
ClientToServerMessage::QueueBlock { .. } => ClientToServerMessageType::QueueBlock,
}
}
}
#[repr(u8)]
#[non_exhaustive]
pub enum ServerToClientMessageType {
ServerHello = 0,
ServerFuckOff = 1,
PlayerPositionChanged = 2,
ChunkResponse = 3,
QueueBlock = 4,
PlayerConnected = 5,
PlayerDisconnected = 6,
}
#[serde_with::serde_as] #[serde_with::serde_as]
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
#[repr(u8)] #[repr(u8)]
#[non_exhaustive]
pub enum ServerToClientMessage { pub enum ServerToClientMessage {
ServerHello { ServerHello {
init: InitData init: InitData
} = S_SERVER_HELLO, } = ServerToClientMessageType::ServerHello as u8,
ServerFuckOff { ServerFuckOff {
reason: String, reason: String,
} = S_SERVER_FUCK_OFF, } = ServerToClientMessageType::ServerFuckOff as u8,
PlayerPositionChanged { PlayerPositionChanged {
client_id: ClientId, client_id: ClientId,
position: Vec3, position: Vec3,
direction: Quat, direction: Quat,
} = S_PLAYER_POSITION_CHANGED, } = ServerToClientMessageType::PlayerPositionChanged as u8,
///## WARNING: THIS IS COMPRESSED ///## WARNING: THIS IS COMPRESSED
///MESSAGES OF THIS TYPE ARE FULLY ///MESSAGES OF THIS TYPE ARE FULLY
@ -69,19 +95,33 @@ pub enum ServerToClientMessage {
#[serde_as(as = "Box<[[[_; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>")] #[serde_as(as = "Box<[[[_; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]>")]
data: BlockData, data: BlockData,
queued: Vec<QueuedBlock>, queued: Vec<QueuedBlock>,
} = S_CHUNK_RESPONSE, } = ServerToClientMessageType::ChunkResponse as u8,
QueueBlock { QueueBlock {
item: QueuedBlock item: QueuedBlock
} = S_QUEUE_BLOCK, } = ServerToClientMessageType::QueueBlock as u8,
PlayerConnected { PlayerConnected {
init: ClientInitData init: ClientInitData
} = S_PLAYER_CONNECTED, } = ServerToClientMessageType::PlayerConnected as u8,
PlayerDisconnected { PlayerDisconnected {
id: ClientId id: ClientId
} = S_PLAYER_DISCONNECTED, } = ServerToClientMessageType::PlayerDisconnected as u8,
}
impl ToMessageType<ServerToClientMessageType> for ServerToClientMessage {
fn message_type(&self) -> ServerToClientMessageType {
match self {
ServerToClientMessage::ServerHello { .. } => ServerToClientMessageType::ServerHello,
ServerToClientMessage::ServerFuckOff { .. } => ServerToClientMessageType::ServerFuckOff,
ServerToClientMessage::PlayerPositionChanged { .. } => ServerToClientMessageType::PlayerPositionChanged,
ServerToClientMessage::ChunkResponse { .. } => ServerToClientMessageType::ChunkResponse,
ServerToClientMessage::QueueBlock { .. } => ServerToClientMessageType::QueueBlock,
ServerToClientMessage::PlayerConnected { .. } => ServerToClientMessageType::PlayerConnected,
ServerToClientMessage::PlayerDisconnected { .. } => ServerToClientMessageType::PlayerDisconnected,
}
}
} }
//--- //---

View file

@ -29,7 +29,7 @@ pub(crate) mod delta_time;
pub(crate) mod cursor_lock; pub(crate) mod cursor_lock;
pub(crate) mod control_flow; pub(crate) mod control_flow;
pub(crate) mod state; pub(crate) mod state;
pub(crate) mod guiv2_integration; pub(crate) mod kubi_ui_integration;
pub(crate) mod networking; pub(crate) mod networking;
pub(crate) mod init; pub(crate) mod init;
pub(crate) mod color; pub(crate) mod color;
@ -76,7 +76,7 @@ use control_flow::{exit_on_esc, insert_control_flow_unique, RequestExit};
use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state, is_connecting}; use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state, is_connecting};
use networking::{update_networking, update_networking_late, is_multiplayer, disconnect_on_exit, is_singleplayer}; use networking::{update_networking, update_networking_late, is_multiplayer, disconnect_on_exit, is_singleplayer};
use init::initialize_from_args; use init::initialize_from_args;
use guiv2_integration::{kubi_ui_init, kubi_ui_begin, kubi_ui_end, kubi_ui_draw}; use kubi_ui_integration::{kubi_ui_init, kubi_ui_begin, kubi_ui_end, kubi_ui_draw};
use loading_screen::update_loading_screen; use loading_screen::update_loading_screen;
use connecting_screen::switch_to_loading_if_connected; use connecting_screen::switch_to_loading_if_connected;
use fixed_timestamp::init_fixed_timestamp_storage; use fixed_timestamp::init_fixed_timestamp_storage;

View file

@ -6,7 +6,7 @@ use crate::{
state::{GameState, NextState}, state::{GameState, NextState},
rendering::WindowSize, rendering::WindowSize,
input::RawKbmInputState, input::RawKbmInputState,
guiv2_integration::UiState, kubi_ui_integration::UiState,
}; };
fn render_progressbar( fn render_progressbar(

View file

@ -1,11 +1,9 @@
use shipyard::{UniqueViewMut, View, IntoIter, AllStoragesViewMut}; use shipyard::{UniqueViewMut, View, IntoIter, AllStoragesViewMut};
use uflow::{client::Event as ClientEvent, SendMode}; use uflow::{client::Event as ClientEvent, SendMode};
use kubi_shared::{ use kubi_shared::networking::{
networking::{ messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType},
messages::{ClientToServerMessage, ServerToClientMessage, S_SERVER_HELLO}, state::ClientJoinState,
state::ClientJoinState, channels::Channel,
channels::CHANNEL_AUTH,
},
}; };
use crate::player::{spawn_local_player_multiplayer, spawn_remote_player_multiplayer}; use crate::player::{spawn_local_player_multiplayer, spawn_remote_player_multiplayer};
use super::{UdpClient, NetworkEvent}; use super::{UdpClient, NetworkEvent};
@ -27,7 +25,7 @@ pub fn say_hello(
postcard::to_allocvec( postcard::to_allocvec(
&ClientToServerMessage::ClientHello { username, password } &ClientToServerMessage::ClientHello { username, password }
).unwrap().into_boxed_slice(), ).unwrap().into_boxed_slice(),
CHANNEL_AUTH, Channel::Auth as usize,
SendMode::Reliable SendMode::Reliable
); );
} }
@ -40,7 +38,7 @@ pub fn check_server_hello_response(
let ClientEvent::Receive(data) = &event.0 else { let ClientEvent::Receive(data) = &event.0 else {
return None return None
}; };
if !event.is_message_of_type::<S_SERVER_HELLO>() { if !event.is_message_of_type::<{ServerToClientMessageType::ServerHello as u8}>() {
return None return None
} }
let Ok(parsed_message) = postcard::from_bytes(data) else { let Ok(parsed_message) = postcard::from_bytes(data) else {

View file

@ -4,10 +4,10 @@ use uflow::{SendMode, client::Event as ClientEvent};
use kubi_shared::{ use kubi_shared::{
transform::Transform, transform::Transform,
networking::{ networking::{
messages::{ClientToServerMessage, ServerToClientMessage, S_PLAYER_POSITION_CHANGED, S_PLAYER_CONNECTED}, messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType},
channels::CHANNEL_MOVE, channels::Channel,
client::ClientIdMap, client::ClientIdMap,
}, },
}; };
use crate::{ use crate::{
events::player_actions::PlayerActionEvent, events::player_actions::PlayerActionEvent,
@ -35,7 +35,7 @@ pub fn send_player_movement_events(
velocity: Vec3::ZERO, velocity: Vec3::ZERO,
direction: *direction direction: *direction
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_MOVE, Channel::Move as usize,
SendMode::TimeSensitive SendMode::TimeSensitive
); );
} }
@ -51,7 +51,7 @@ pub fn receive_player_movement_events(
continue continue
}; };
if !event.is_message_of_type::<S_PLAYER_POSITION_CHANGED>() { if !event.is_message_of_type::<{ServerToClientMessageType::PlayerPositionChanged as u8}>() {
continue continue
} }
@ -83,7 +83,7 @@ pub fn receive_player_connect_events(
let ClientEvent::Receive(data) = &event.0 else { let ClientEvent::Receive(data) = &event.0 else {
return None return None
}; };
if !event.is_message_of_type::<S_PLAYER_CONNECTED>() { if !event.is_message_of_type::<{ServerToClientMessageType::PlayerConnected as u8}>() {
return None return None
}; };
let Ok(parsed_message) = postcard::from_bytes(data) else { let Ok(parsed_message) = postcard::from_bytes(data) else {

View file

@ -4,9 +4,9 @@ use lz4_flex::decompress_size_prepended;
use anyhow::{Result, Context}; use anyhow::{Result, Context};
use kubi_shared::{ use kubi_shared::{
networking::{ networking::{
messages::{ClientToServerMessage, ServerToClientMessage, S_CHUNK_RESPONSE, S_QUEUE_BLOCK}, messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType},
channels::CHANNEL_BLOCK, channels::Channel,
}, },
queue::QueuedBlock queue::QueuedBlock
}; };
use crate::{ use crate::{
@ -31,7 +31,7 @@ pub fn inject_network_responses_into_manager_queue(
events: View<NetworkEvent> events: View<NetworkEvent>
) { ) {
for event in events.iter() { for event in events.iter() {
if event.is_message_of_type::<S_CHUNK_RESPONSE>() { if event.is_message_of_type::<{ServerToClientMessageType::ChunkResponse as u8}>() {
let NetworkEvent(ClientEvent::Receive(data)) = &event else { unreachable!() }; let NetworkEvent(ClientEvent::Receive(data)) = &event else { unreachable!() };
let packet = decompress_chunk_packet(data).expect("Chunk decode failed"); let packet = decompress_chunk_packet(data).expect("Chunk decode failed");
let ServerToClientMessage::ChunkResponse { let ServerToClientMessage::ChunkResponse {
@ -56,13 +56,13 @@ pub fn send_block_place_events(
}; };
client.0.send( client.0.send(
postcard::to_allocvec(&ClientToServerMessage::QueueBlock { postcard::to_allocvec(&ClientToServerMessage::QueueBlock {
item: QueuedBlock { item: QueuedBlock {
position: *position, position: *position,
block_type: *block, block_type: *block,
soft: false soft: false
} }
}).unwrap().into_boxed_slice(), }).unwrap().into_boxed_slice(),
CHANNEL_BLOCK, Channel::Block as usize,
SendMode::Reliable, SendMode::Reliable,
); );
} }
@ -76,7 +76,7 @@ pub fn recv_block_place_events(
let ClientEvent::Receive(data) = &event.0 else { let ClientEvent::Receive(data) = &event.0 else {
continue continue
}; };
if !event.is_message_of_type::<S_QUEUE_BLOCK>() { if !event.is_message_of_type::<{ServerToClientMessageType::QueueBlock as u8}>() {
continue continue
} }
let Ok(parsed_message) = postcard::from_bytes(data) else { let Ok(parsed_message) = postcard::from_bytes(data) else {

View file

@ -17,7 +17,7 @@ use super::{
primitives::cube::CubePrimitive, primitives::cube::CubePrimitive,
}; };
const SMOL: f32 = 0.0001; const SMOL: f32 = 0.0025;
pub fn render_selection_box( pub fn render_selection_box(
lookat: View<LookingAtBlock>, lookat: View<LookingAtBlock>,