mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-12-26 21:58:20 -06:00
wip
This commit is contained in:
parent
8d7b51707f
commit
b18756bb7e
|
@ -33,6 +33,7 @@ pub fn authenticate_players(
|
||||||
let config = storages.borrow::<UniqueView<ConfigTable>>().unwrap();
|
let config = storages.borrow::<UniqueView<ConfigTable>>().unwrap();
|
||||||
|
|
||||||
for event in &events.0 {
|
for event in &events.0 {
|
||||||
|
// NOT using `check_message_auth` here because the user is not authed yet!
|
||||||
let ServerEvent::Receive(client_addr, data) = event else{
|
let ServerEvent::Receive(client_addr, data) = event else{
|
||||||
continue
|
continue
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
use shipyard::{Component, EntityId, Unique, AllStoragesView, UniqueView, NonSendSync, View, Get};
|
use glam::Mat4;
|
||||||
|
use shipyard::{Component, EntityId, Unique, AllStoragesView, UniqueView, NonSendSync, View, ViewMut, Get};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use uflow::server::Event as ServerEvent;
|
use kubi_shared::{
|
||||||
use kubi_shared::networking::{
|
networking::{
|
||||||
client::{ClientIdMap, Client},
|
client::{ClientIdMap, Client},
|
||||||
messages::{ClientToServerMessage, C_POSITION_CHANGED}
|
messages::{ClientToServerMessage, C_POSITION_CHANGED}
|
||||||
|
},
|
||||||
|
transform::Transform
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
|
server::{ServerEvents, UdpServer},
|
||||||
|
util::check_message_auth
|
||||||
};
|
};
|
||||||
use crate::server::{ServerEvents, IsMessageOfType, UdpServer};
|
|
||||||
|
|
||||||
#[derive(Component, Clone, Copy)]
|
#[derive(Component, Clone, Copy)]
|
||||||
pub struct ClientAddress(pub SocketAddr);
|
pub struct ClientAddress(pub SocketAddr);
|
||||||
|
@ -29,34 +35,18 @@ pub fn sync_client_positions(
|
||||||
events: UniqueView<ServerEvents>,
|
events: UniqueView<ServerEvents>,
|
||||||
addr_map: UniqueView<ClientAddressMap>,
|
addr_map: UniqueView<ClientAddressMap>,
|
||||||
clients: View<Client>,
|
clients: View<Client>,
|
||||||
|
mut transforms: ViewMut<Transform>
|
||||||
) {
|
) {
|
||||||
for event in &events.0 {
|
for event in &events.0 {
|
||||||
let ServerEvent::Receive(client_addr, data) = event else{
|
let Some(message) = check_message_auth::<C_POSITION_CHANGED>(&server, event, &clients, &addr_map) else {
|
||||||
continue
|
continue;
|
||||||
};
|
};
|
||||||
if !event.is_message_of_type::<C_POSITION_CHANGED>() {
|
let ClientToServerMessage::PositionChanged { position, velocity: _, direction } = message.message else {
|
||||||
continue
|
|
||||||
}
|
|
||||||
let Some(client) = server.0.client(client_addr) else {
|
|
||||||
log::error!("Client doesn't exist");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let Some(&entity_id) = addr_map.0.get(client_addr) else {
|
|
||||||
log::error!("Client not authenticated");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let Ok(&Client(client_id)) = (&clients).get(entity_id) else {
|
|
||||||
log::error!("Entity ID is invalid");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let Ok(parsed_message) = postcard::from_bytes(data) else {
|
|
||||||
log::error!("Malformed message");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let ClientToServerMessage::PositionChanged { position, velocity, direction } = parsed_message else {
|
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
//Apply position to client
|
||||||
|
let mut trans = (&mut transforms).get(message.entity_id).unwrap();
|
||||||
|
trans.0 = Mat4::from_rotation_translation(direction, position);
|
||||||
|
|
||||||
//TODO: sync positions on server
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use shipyard::{World, Workload, IntoWorkload};
|
use shipyard::{World, Workload, IntoWorkload};
|
||||||
use std::{thread, time::Duration};
|
use std::{thread, time::Duration};
|
||||||
|
|
||||||
|
mod util;
|
||||||
mod config;
|
mod config;
|
||||||
mod server;
|
mod server;
|
||||||
mod client;
|
mod client;
|
||||||
|
|
72
kubi-server/src/util.rs
Normal file
72
kubi-server/src/util.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
use std::{net::SocketAddr, rc::Rc, cell::RefCell};
|
||||||
|
use shipyard::{View, Get, EntityId};
|
||||||
|
use uflow::server::{Event as ServerEvent, RemoteClient};
|
||||||
|
use kubi_shared::networking::{
|
||||||
|
messages::ClientToServerMessage,
|
||||||
|
client::{Client, ClientId}
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
|
server::{IsMessageOfType, UdpServer},
|
||||||
|
client::ClientAddressMap
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CtsMessageMetadata<'a> {
|
||||||
|
pub message: ClientToServerMessage,
|
||||||
|
pub client_id: ClientId,
|
||||||
|
pub entity_id: EntityId,
|
||||||
|
pub client_addr: SocketAddr,
|
||||||
|
pub client: &'a Rc<RefCell<RemoteClient>>,
|
||||||
|
}
|
||||||
|
impl From<CtsMessageMetadata<'_>> for ClientToServerMessage {
|
||||||
|
fn from(value: CtsMessageMetadata) -> Self { value.message }
|
||||||
|
}
|
||||||
|
impl From<CtsMessageMetadata<'_>> for ClientId {
|
||||||
|
fn from(value: CtsMessageMetadata) -> Self { value.client_id }
|
||||||
|
}
|
||||||
|
impl From<CtsMessageMetadata<'_>> for EntityId {
|
||||||
|
fn from(value: CtsMessageMetadata) -> Self { value.entity_id }
|
||||||
|
}
|
||||||
|
impl From<CtsMessageMetadata<'_>> for SocketAddr {
|
||||||
|
fn from(value: CtsMessageMetadata) -> Self { value.client_addr }
|
||||||
|
}
|
||||||
|
impl<'a> From<CtsMessageMetadata<'a>> for &'a Rc<RefCell<RemoteClient>> {
|
||||||
|
fn from(value: CtsMessageMetadata<'a>) -> Self { value.client }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn check_message_auth<'a, const C_MSG: u8>(
|
||||||
|
server: &'a UdpServer,
|
||||||
|
event: &ServerEvent,
|
||||||
|
clients: &View<Client>,
|
||||||
|
addr_map: &ClientAddressMap
|
||||||
|
) -> Option<CtsMessageMetadata<'a>> {
|
||||||
|
let ServerEvent::Receive(client_addr, data) = event else{
|
||||||
|
return None
|
||||||
|
};
|
||||||
|
if !event.is_message_of_type::<C_MSG>() {
|
||||||
|
return None
|
||||||
|
}
|
||||||
|
let Some(client) = server.0.client(client_addr) else {
|
||||||
|
log::error!("Client doesn't exist");
|
||||||
|
return None
|
||||||
|
};
|
||||||
|
let Some(&entity_id) = addr_map.0.get(client_addr) else {
|
||||||
|
log::error!("Client not authenticated");
|
||||||
|
return None
|
||||||
|
};
|
||||||
|
let Ok(&Client(client_id)) = (&clients).get(entity_id) else {
|
||||||
|
log::error!("Entity ID is invalid");
|
||||||
|
return None
|
||||||
|
};
|
||||||
|
let Ok(message) = postcard::from_bytes(data) else {
|
||||||
|
log::error!("Malformed message");
|
||||||
|
return None
|
||||||
|
};
|
||||||
|
Some(CtsMessageMetadata {
|
||||||
|
message,
|
||||||
|
client_id,
|
||||||
|
entity_id,
|
||||||
|
client_addr: *client_addr,
|
||||||
|
client
|
||||||
|
})
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ use crate::{
|
||||||
server::{UdpServer, ServerEvents, IsMessageOfType},
|
server::{UdpServer, ServerEvents, IsMessageOfType},
|
||||||
config::ConfigTable,
|
config::ConfigTable,
|
||||||
client::{ClientAddress, ClientAddressMap},
|
client::{ClientAddress, ClientAddressMap},
|
||||||
|
util::check_message_auth,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod chunk;
|
pub mod chunk;
|
||||||
|
@ -61,38 +62,19 @@ fn process_chunk_requests(
|
||||||
clients: View<Client>
|
clients: View<Client>
|
||||||
) {
|
) {
|
||||||
for event in &events.0 {
|
for event in &events.0 {
|
||||||
let ServerEvent::Receive(client_addr, data) = event else{
|
let Some(message) = check_message_auth::<C_CHUNK_SUB_REQUEST>(&server, event, &clients, &addr_map) else {
|
||||||
continue
|
continue;
|
||||||
};
|
};
|
||||||
if !event.is_message_of_type::<C_CHUNK_SUB_REQUEST>() {
|
let ClientToServerMessage::ChunkSubRequest { chunk: chunk_position } = message.message else {
|
||||||
continue
|
|
||||||
}
|
|
||||||
let Some(client) = server.0.client(client_addr) else {
|
|
||||||
log::error!("Client doesn't exist");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let Some(&entity_id) = addr_map.0.get(client_addr) else {
|
|
||||||
log::error!("Client not authenticated");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let Ok(&Client(client_id)) = (&clients).get(entity_id) else {
|
|
||||||
log::error!("Entity ID is invalid");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let Ok(parsed_message) = postcard::from_bytes(data) else {
|
|
||||||
log::error!("Malformed message");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let ClientToServerMessage::ChunkSubRequest { chunk: chunk_position } = parsed_message else {
|
|
||||||
unreachable!()
|
unreachable!()
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(chunk) = chunk_manager.chunks.get_mut(&chunk_position) {
|
if let Some(chunk) = chunk_manager.chunks.get_mut(&chunk_position) {
|
||||||
chunk.subscriptions.insert(client_id);
|
chunk.subscriptions.insert(message.client_id);
|
||||||
//TODO Start task here if status is "Nothing"
|
//TODO Start task here if status is "Nothing"
|
||||||
if let Some(blocks) = &chunk.blocks {
|
if let Some(blocks) = &chunk.blocks {
|
||||||
send_chunk_compressed(
|
send_chunk_compressed(
|
||||||
&client,
|
&message.client,
|
||||||
&ServerToClientMessage::ChunkResponse {
|
&ServerToClientMessage::ChunkResponse {
|
||||||
chunk: chunk_position,
|
chunk: chunk_position,
|
||||||
data: blocks.clone(),
|
data: blocks.clone(),
|
||||||
|
@ -103,7 +85,7 @@ fn process_chunk_requests(
|
||||||
} else {
|
} else {
|
||||||
let mut chunk = Chunk::new(chunk_position);
|
let mut chunk = Chunk::new(chunk_position);
|
||||||
chunk.state = ChunkState::Loading;
|
chunk.state = ChunkState::Loading;
|
||||||
chunk.subscriptions.insert(client_id);
|
chunk.subscriptions.insert(message.client_id);
|
||||||
chunk_manager.chunks.insert(chunk_position, chunk);
|
chunk_manager.chunks.insert(chunk_position, chunk);
|
||||||
task_manager.spawn_task(ChunkTask::LoadChunk {
|
task_manager.spawn_task(ChunkTask::LoadChunk {
|
||||||
position: chunk_position,
|
position: chunk_position,
|
||||||
|
@ -172,32 +154,15 @@ fn process_block_queue_messages(
|
||||||
addrs: View<ClientAddress>,
|
addrs: View<ClientAddress>,
|
||||||
) {
|
) {
|
||||||
for event in &events.0 {
|
for event in &events.0 {
|
||||||
let ServerEvent::Receive(client_addr, data) = event else{
|
let Some(message) = check_message_auth::<C_QUEUE_BLOCK>(&server, event, &clients, &addr_map) else {
|
||||||
continue
|
continue;
|
||||||
};
|
|
||||||
if !event.is_message_of_type::<C_QUEUE_BLOCK>() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
let Some(&entity_id) = addr_map.0.get(client_addr) else {
|
|
||||||
log::error!("Client not authenticated");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let Ok(&Client(client_id)) = (&clients).get(entity_id) else {
|
|
||||||
log::error!("Entity ID is invalid");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let Ok(parsed_message) = postcard::from_bytes(data) else {
|
|
||||||
log::error!("Malformed message");
|
|
||||||
continue
|
|
||||||
};
|
|
||||||
let ClientToServerMessage::QueueBlock { item } = parsed_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 client_id == other_client.0 {
|
if message.client_id == other_client.0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//Get client
|
//Get client
|
||||||
|
|
|
@ -9,9 +9,26 @@ flat in uint v_tex_index;
|
||||||
out vec4 color;
|
out vec4 color;
|
||||||
uniform sampler2DArray tex;
|
uniform sampler2DArray tex;
|
||||||
|
|
||||||
|
vec4 alpha_drop(vec4 b, vec4 a) {
|
||||||
|
if ((a.w < 1.) || (b.w < 1.)) {
|
||||||
|
return vec4(b.xyz, 0.);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// base color from texture
|
// base color from texture
|
||||||
color = texture(tex, vec3(v_uv, v_tex_index));
|
color = texture(tex, vec3(v_uv, v_tex_index));
|
||||||
|
// HACKY texture "antialiasing"
|
||||||
|
color += (
|
||||||
|
alpha_drop(color, texture(tex, vec3(v_uv + vec2(.000, .001), v_tex_index))) +
|
||||||
|
alpha_drop(color, texture(tex, vec3(v_uv + vec2(.001, .000), v_tex_index))) +
|
||||||
|
alpha_drop(color, texture(tex, vec3(v_uv + vec2(.001, .001), v_tex_index))) +
|
||||||
|
alpha_drop(color, texture(tex, vec3(v_uv - vec2(.000, .001), v_tex_index))) +
|
||||||
|
alpha_drop(color, texture(tex, vec3(v_uv - vec2(.001, .000), v_tex_index))) +
|
||||||
|
alpha_drop(color, texture(tex, vec3(v_uv - vec2(.001, .001), v_tex_index)))
|
||||||
|
) / 6.;
|
||||||
|
color /= 2.;
|
||||||
// discard fully transparent pixels
|
// discard fully transparent pixels
|
||||||
if (color.w <= 0.0) {
|
if (color.w <= 0.0) {
|
||||||
discard;
|
discard;
|
||||||
|
|
|
@ -78,7 +78,7 @@ use delta_time::{DeltaTime, init_delta_time};
|
||||||
use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now};
|
use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now};
|
||||||
use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow};
|
use control_flow::{exit_on_esc, insert_control_flow_unique, SetControlFlow};
|
||||||
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};
|
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 gui::{render_gui, init_gui, update_gui};
|
use gui::{render_gui, init_gui, update_gui};
|
||||||
use loading_screen::update_loading_screen;
|
use loading_screen::update_loading_screen;
|
||||||
|
@ -114,7 +114,9 @@ fn update() -> Workload {
|
||||||
process_inputs,
|
process_inputs,
|
||||||
(
|
(
|
||||||
init_game_world.run_if_missing_unique::<ChunkTaskManager>(),
|
init_game_world.run_if_missing_unique::<ChunkTaskManager>(),
|
||||||
spawn_player.run_if_storage_empty::<MainPlayer>(),
|
(
|
||||||
|
spawn_player.run_if_storage_empty::<MainPlayer>(),
|
||||||
|
).into_sequential_workload().run_if(is_singleplayer),
|
||||||
).into_sequential_workload().run_if(is_ingame_or_loading),
|
).into_sequential_workload().run_if(is_ingame_or_loading),
|
||||||
update_networking.run_if(is_multiplayer),
|
update_networking.run_if(is_multiplayer),
|
||||||
(
|
(
|
||||||
|
|
|
@ -5,6 +5,7 @@ use uflow::{client::{Client, Config as ClientConfig, Event as ClientEvent}, Endp
|
||||||
use kubi_shared::networking::{
|
use kubi_shared::networking::{
|
||||||
messages::ServerToClientMessage,
|
messages::ServerToClientMessage,
|
||||||
state::ClientJoinState,
|
state::ClientJoinState,
|
||||||
|
client::ClientIdMap,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
events::EventComponent,
|
events::EventComponent,
|
||||||
|
@ -27,7 +28,10 @@ use world::{
|
||||||
send_block_place_events,
|
send_block_place_events,
|
||||||
recv_block_place_events,
|
recv_block_place_events,
|
||||||
};
|
};
|
||||||
use player::send_player_movement_events;
|
use player::{
|
||||||
|
init_client_map,
|
||||||
|
send_player_movement_events,
|
||||||
|
};
|
||||||
|
|
||||||
use self::player::{receive_player_movement_events, receive_player_connect_events};
|
use self::player::{receive_player_movement_events, receive_player_connect_events};
|
||||||
|
|
||||||
|
@ -111,6 +115,7 @@ fn handle_disconnect(
|
||||||
|
|
||||||
pub fn update_networking() -> Workload {
|
pub fn update_networking() -> Workload {
|
||||||
(
|
(
|
||||||
|
init_client_map.run_if_missing_unique::<ClientIdMap>(),
|
||||||
connect_client.run_if_missing_unique::<UdpClient>(),
|
connect_client.run_if_missing_unique::<UdpClient>(),
|
||||||
poll_client,
|
poll_client,
|
||||||
(
|
(
|
||||||
|
|
|
@ -1,17 +1,15 @@
|
||||||
use glam::Mat4;
|
use shipyard::{UniqueViewMut, View, IntoIter, AllStoragesViewMut};
|
||||||
use shipyard::{UniqueViewMut, View, IntoIter, AllStoragesViewMut, ViewMut, IntoWithId};
|
|
||||||
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, S_SERVER_HELLO},
|
messages::{ClientToServerMessage, ServerToClientMessage, S_SERVER_HELLO},
|
||||||
state::ClientJoinState,
|
state::ClientJoinState,
|
||||||
channels::CHANNEL_AUTH,
|
channels::CHANNEL_AUTH,
|
||||||
client::{Username, Client},
|
client::Username,
|
||||||
},
|
},
|
||||||
transform::Transform, entity::Health
|
|
||||||
};
|
};
|
||||||
use crate::player::MainPlayer;
|
use crate::player::{MainPlayer, spawn_local_player_multiplayer, spawn_remote_player_multiplayer};
|
||||||
use super::{UdpClient, NetworkEvent, player::add_net_player};
|
use super::{UdpClient, NetworkEvent};
|
||||||
|
|
||||||
pub fn set_client_join_state_to_connected(
|
pub fn set_client_join_state_to_connected(
|
||||||
mut join_state: UniqueViewMut<ClientJoinState>
|
mut join_state: UniqueViewMut<ClientJoinState>
|
||||||
|
@ -25,7 +23,7 @@ pub fn say_hello(
|
||||||
main_player: View<MainPlayer>,
|
main_player: View<MainPlayer>,
|
||||||
username: View<Username>
|
username: View<Username>
|
||||||
) {
|
) {
|
||||||
let username = (&main_player, &username).iter().next().unwrap().1.0.clone();
|
let username = "XxX-FishFucker-69420-XxX".into(); //(&main_player, &username).iter().next().unwrap().1.0.clone();
|
||||||
let password = None;
|
let password = None;
|
||||||
log::info!("Authenticating");
|
log::info!("Authenticating");
|
||||||
client.0.send(
|
client.0.send(
|
||||||
|
@ -68,28 +66,11 @@ pub fn check_server_hello_response(
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//Add components to main player
|
//Add components to main player
|
||||||
{
|
spawn_local_player_multiplayer(&mut storages, init.user);
|
||||||
let entity = (&storages.borrow::<View<MainPlayer>>().unwrap()).iter().with_id().next().unwrap().0;
|
|
||||||
storages.add_component(entity, Client(init.user.client_id));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Modify main player
|
|
||||||
{
|
|
||||||
for (entity, (_, mut username, mut transform, mut health)) in (
|
|
||||||
&storages.borrow::<View<MainPlayer>>().unwrap(),
|
|
||||||
&mut storages.borrow::<ViewMut<Username>>().unwrap(),
|
|
||||||
&mut storages.borrow::<ViewMut<Transform>>().unwrap(),
|
|
||||||
&mut storages.borrow::<ViewMut<Health>>().unwrap(),
|
|
||||||
).iter().with_id() {
|
|
||||||
username.0 = init.user.username.clone();
|
|
||||||
transform.0 = Mat4::from_rotation_translation(init.user.direction, init.user.position);
|
|
||||||
*health = init.user.health;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Init players
|
//Init players
|
||||||
for init_data in init.users {
|
for init_data in init.users {
|
||||||
add_net_player(&mut storages, init_data);
|
spawn_remote_player_multiplayer(&mut storages, init_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set state to connected
|
// Set state to connected
|
||||||
|
|
|
@ -2,16 +2,17 @@ use glam::{Vec3, Mat4};
|
||||||
use shipyard::{UniqueViewMut, View, IntoIter, AllStoragesView, AllStoragesViewMut, UniqueView, ViewMut, Get};
|
use shipyard::{UniqueViewMut, View, IntoIter, AllStoragesView, AllStoragesViewMut, UniqueView, ViewMut, Get};
|
||||||
use uflow::{SendMode, client::Event as ClientEvent};
|
use uflow::{SendMode, client::Event as ClientEvent};
|
||||||
use kubi_shared::{
|
use kubi_shared::{
|
||||||
player::{Player, PlayerHolding},
|
|
||||||
entity::Entity,
|
|
||||||
transform::Transform,
|
transform::Transform,
|
||||||
networking::{
|
networking::{
|
||||||
messages::{ClientToServerMessage, ServerToClientMessage, S_PLAYER_POSITION_CHANGED, ClientInitData},
|
messages::{ClientToServerMessage, ServerToClientMessage, S_PLAYER_POSITION_CHANGED},
|
||||||
channels::CHANNEL_MOVE,
|
channels::CHANNEL_MOVE,
|
||||||
client::{ClientIdMap, Username, Client},
|
client::ClientIdMap,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::events::player_actions::PlayerActionEvent;
|
use crate::{
|
||||||
|
events::player_actions::PlayerActionEvent,
|
||||||
|
player::spawn_remote_player_multiplayer,
|
||||||
|
};
|
||||||
use super::{UdpClient, NetworkEvent};
|
use super::{UdpClient, NetworkEvent};
|
||||||
|
|
||||||
pub fn init_client_map(
|
pub fn init_client_map(
|
||||||
|
@ -20,35 +21,6 @@ pub fn init_client_map(
|
||||||
storages.add_unique(ClientIdMap::new());
|
storages.add_unique(ClientIdMap::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_net_player(
|
|
||||||
storages: &mut AllStoragesViewMut,
|
|
||||||
init: ClientInitData
|
|
||||||
) {
|
|
||||||
// struct ClientInitData {
|
|
||||||
// client_id: ClientId,
|
|
||||||
// username: String,
|
|
||||||
// position: Vec3,
|
|
||||||
// velocity: Vec3,
|
|
||||||
// direction: Quat,
|
|
||||||
// health: Health,
|
|
||||||
// }
|
|
||||||
|
|
||||||
//Spawn player locally
|
|
||||||
let entity_id = storages.add_entity((
|
|
||||||
Username(init.username),
|
|
||||||
Client(init.client_id),
|
|
||||||
Player,
|
|
||||||
Entity,
|
|
||||||
init.health,
|
|
||||||
Transform(Mat4::from_rotation_translation(init.direction, init.position)),
|
|
||||||
PlayerHolding::default(),
|
|
||||||
));
|
|
||||||
|
|
||||||
//Add it to the client id map
|
|
||||||
let mut client_id_map = storages.borrow::<UniqueViewMut<ClientIdMap>>().unwrap();
|
|
||||||
client_id_map.0.insert(init.client_id, entity_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn send_player_movement_events(
|
pub fn send_player_movement_events(
|
||||||
actions: View<PlayerActionEvent>,
|
actions: View<PlayerActionEvent>,
|
||||||
mut client: UniqueViewMut<UdpClient>,
|
mut client: UniqueViewMut<UdpClient>,
|
||||||
|
@ -124,6 +96,6 @@ pub fn receive_player_connect_events(
|
||||||
for message in messages {
|
for message in messages {
|
||||||
let ServerToClientMessage::PlayerConnected { init } = message else { unreachable!() };
|
let ServerToClientMessage::PlayerConnected { init } = message else { unreachable!() };
|
||||||
log::info!("player connected: {} (id {})", init.username, init.client_id);
|
log::info!("player connected: {} (id {})", init.username, init.client_id);
|
||||||
add_net_player(&mut storages, init);
|
spawn_remote_player_multiplayer(&mut storages, init);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
use shipyard::{Component, AllStoragesViewMut};
|
use glam::Mat4;
|
||||||
|
use shipyard::{Component, AllStoragesViewMut, UniqueViewMut};
|
||||||
use kubi_shared::{
|
use kubi_shared::{
|
||||||
entity::{Entity, Health},
|
entity::{Entity, Health},
|
||||||
player::{PLAYER_HEALTH, PlayerHolding},
|
player::{PLAYER_HEALTH, PlayerHolding},
|
||||||
networking::client::Username
|
networking::{
|
||||||
|
client::{Username, Client, ClientIdMap},
|
||||||
|
messages::ClientInitData
|
||||||
|
}
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
transform::Transform,
|
transform::Transform,
|
||||||
|
@ -16,7 +20,7 @@ pub use kubi_shared::player::Player;
|
||||||
pub struct MainPlayer;
|
pub struct MainPlayer;
|
||||||
|
|
||||||
pub fn spawn_player (
|
pub fn spawn_player (
|
||||||
mut storages: AllStoragesViewMut
|
mut storages: AllStoragesViewMut,
|
||||||
) {
|
) {
|
||||||
log::info!("spawning player");
|
log::info!("spawning player");
|
||||||
storages.add_entity((
|
storages.add_entity((
|
||||||
|
@ -29,6 +33,55 @@ pub fn spawn_player (
|
||||||
FlyController,
|
FlyController,
|
||||||
LookingAtBlock::default(),
|
LookingAtBlock::default(),
|
||||||
PlayerHolding::default(),
|
PlayerHolding::default(),
|
||||||
Username("Sbeve".into())
|
Username("LocalPlayer".into())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn spawn_local_player_multiplayer (
|
||||||
|
storages: &mut AllStoragesViewMut,
|
||||||
|
init: ClientInitData
|
||||||
|
) {
|
||||||
|
log::info!("spawning local multiplayer player");
|
||||||
|
let entity_id = storages.add_entity((
|
||||||
|
(
|
||||||
|
Player,
|
||||||
|
Client(init.client_id),
|
||||||
|
MainPlayer,
|
||||||
|
Entity,
|
||||||
|
init.health,
|
||||||
|
Transform(Mat4::from_rotation_translation(init.direction, init.position)),
|
||||||
|
Camera::default(),
|
||||||
|
FlyController,
|
||||||
|
LookingAtBlock::default(),
|
||||||
|
PlayerHolding::default(),
|
||||||
|
),(
|
||||||
|
Username(init.username)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
//Add ourself to the client id map
|
||||||
|
let mut client_id_map = storages.borrow::<UniqueViewMut<ClientIdMap>>().unwrap();
|
||||||
|
client_id_map.0.insert(init.client_id, entity_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_remote_player_multiplayer(
|
||||||
|
storages: &mut AllStoragesViewMut,
|
||||||
|
init: ClientInitData
|
||||||
|
) {
|
||||||
|
log::info!("spawning remote multiplayer player");
|
||||||
|
|
||||||
|
//Spawn player locally
|
||||||
|
let entity_id = storages.add_entity((
|
||||||
|
Username(init.username),
|
||||||
|
Client(init.client_id),
|
||||||
|
Player,
|
||||||
|
Entity,
|
||||||
|
init.health,
|
||||||
|
Transform(Mat4::from_rotation_translation(init.direction, init.position)),
|
||||||
|
PlayerHolding::default(),
|
||||||
|
));
|
||||||
|
|
||||||
|
//Add it to the client id map
|
||||||
|
let mut client_id_map = storages.borrow::<UniqueViewMut<ClientIdMap>>().unwrap();
|
||||||
|
client_id_map.0.insert(init.client_id, entity_id);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue