use std::collections::HashMap; use bevy::prelude::*; use felix_audio::{SAMPLE_RATE, source::{FelixAudioSource, stream_source::StreamAudioSource}}; use felix_net::{packet::PacketTypes, packets::update_server_position::UpdateServerPositions}; use crate::{debug_camera::DebugCamera, net::{NetClientCommand, connection::Connection}, remote_player::RemotePlayer}; pub fn fixed_update( mut query: Query<(&mut DebugCamera, &mut Transform)>, mut networking: Query<&mut Connection>, mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, players: Query<(Entity, &mut RemotePlayer)> ){ let ( _, transform ) = query.single_mut().unwrap(); let mut net_manager = networking.single_mut().unwrap(); let update_pos_packet = UpdateServerPositions { position: transform.translation.clone(), rotation: transform.rotation.clone() }; net_manager.try_send_unreliable(update_pos_packet).unwrap(); if let Ok(ev) = net_manager.recv_event(){ match ev{ NetClientCommand::Connected(id) => { println!("[INFO] Connected to server as {}", id); } NetClientCommand::Disconnected => { println!("[WARN] Disconnected from server."); } NetClientCommand::RecvPacket(packet) => { match packet{ PacketTypes::PlayerJoinPacket(packet) => { join_players(vec![packet.id], &mut commands, &mut meshes, &mut materials, &mut net_manager); } PacketTypes::PlayerListPacket(packet) => { join_players(packet.ids, &mut commands, &mut meshes, &mut materials, &mut net_manager); } PacketTypes::PlayerLeavePacket(packet) => { leave_player(packet.id, &mut commands, players, &mut net_manager); } PacketTypes::UpdateClientsPositions(packet) => { let mut map = HashMap::new(); for ( id, pos, rot ) in packet.players{ map.insert(id, (pos, rot)); } for ( _, mut player ) in players{ let ( pos, rot ) = map.get(&player.id).unwrap(); player.pos = *pos; player.rot = *rot; } } _ => {} } } } } } fn join_players( players: Vec, commands: &mut Commands, meshes: &mut ResMut>, materials: &mut ResMut>, net_manager: &mut Connection ){ for id in players{ let listener = net_manager.start_listening_for_player_voice(&id); commands.spawn(( Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))), MeshMaterial3d(materials.add(Color::WHITE)), Transform::from_xyz(0.0, 0.0, 0.0), RemotePlayer { id, ..Default::default() }, FelixAudioSource::from(StreamAudioSource::new(SAMPLE_RATE, move | len | { let mut buf = vec![0.0; len]; let mut lock = listener.lock().unwrap(); for i in 0..buf.len(){ buf[i] = lock.pop_front().unwrap_or(0.0); } buf })) )); } } fn leave_player( id: String, commands: &mut Commands, players: Query<(Entity, &mut RemotePlayer)>, net_manager: &mut Connection ){ net_manager.stop_listening_for_player_voice(&id); for ( entity, player ) in players{ if id == player.id{ commands.entity(entity).despawn(); break; } } }