+6
-13
audio/src/lib.rs
+6
-13
audio/src/lib.rs
···
1
use bevy::{app::{App, Plugin, Startup, Update}, ecs::{component::Component, system::{Commands, Query}}, math::{Quat, Vec3}, transform::components::Transform};
2
-
use cpal::{BufferSize, SampleRate, StreamConfig};
3
-
use kira::{AudioManager, AudioManagerSettings, DefaultBackend, Tween, backend::cpal::CpalBackendSettings, listener::ListenerHandle};
4
5
use crate::source::FelixAudioSource;
6
···
12
pub mod source;
13
pub mod utils;
14
pub mod voice;
15
16
fn update_audio_system(
17
mut audio_system: Query<&mut FelixAudioComponent>,
···
47
impl Plugin for FelixAudio{
48
fn build(&self, app: &mut App) {
49
app.add_systems(Startup, move | mut commands: Commands | {
50
-
let mut settings = AudioManagerSettings::default();
51
-
settings.backend_settings = CpalBackendSettings {
52
-
config: Some(StreamConfig {
53
-
channels: 2,
54
-
sample_rate: SampleRate(48_000),
55
-
buffer_size: BufferSize::Fixed(512)
56
-
}),
57
-
..Default::default()
58
-
};
59
-
60
-
let mut manager = AudioManager::<DefaultBackend>::new(settings).unwrap();
61
let main_listener = manager.add_listener(Vec3::default(), Quat::default()).unwrap();
62
63
let handle = FelixAudioComponent { manager, main_listener };
···
1
use bevy::{app::{App, Plugin, Startup, Update}, ecs::{component::Component, system::{Commands, Query}}, math::{Quat, Vec3}, transform::components::Transform};
2
+
use kira::{AudioManager, AudioManagerSettings, DefaultBackend, Tween, listener::ListenerHandle};
3
4
use crate::source::FelixAudioSource;
5
···
11
pub mod source;
12
pub mod utils;
13
pub mod voice;
14
+
15
+
// TODO: Make this use HRTF at some point
16
+
// Maybe revisit steam audio?
17
+
// Or just find some other library that does HRTFs.
18
19
fn update_audio_system(
20
mut audio_system: Query<&mut FelixAudioComponent>,
···
50
impl Plugin for FelixAudio{
51
fn build(&self, app: &mut App) {
52
app.add_systems(Startup, move | mut commands: Commands | {
53
+
let mut manager = AudioManager::<DefaultBackend>::new(AudioManagerSettings::default()).unwrap();
54
let main_listener = manager.add_listener(Vec3::default(), Quat::default()).unwrap();
55
56
let handle = FelixAudioComponent { manager, main_listener };
+18
-3
audio/src/voice/decoder.rs
+18
-3
audio/src/voice/decoder.rs
···
1
-
use std::{collections::VecDeque, sync::{Arc, Mutex, mpsc::{Sender, channel}}, thread};
2
3
use opus::{Channels, Decoder};
4
5
use crate::{MONO_20MS, SAMPLE_RATE};
6
7
pub struct VoiceChatDecoder{
8
-
stream_in: Sender<Vec<u8>>
9
}
10
11
impl VoiceChatDecoder{
···
13
let mut decoder = Decoder::new(SAMPLE_RATE as u32, Channels::Mono).unwrap();
14
let ( stream_in, stream_out ) = channel();
15
16
thread::spawn(move || {
17
let mut buffer = [0.0; MONO_20MS];
18
···
20
let packet: Vec<u8> = stream_out.recv().unwrap();
21
decoder.decode_float(&packet, &mut buffer, false).unwrap();
22
23
let mut voice = queue.lock().unwrap();
24
for sample in buffer{ voice.push_back(sample); }
25
}
26
});
27
28
-
Self { stream_in }
29
}
30
31
pub fn decode( &self, packet: Vec<u8> ){
32
self.stream_in.send(packet).unwrap();
33
}
34
}
···
1
+
use std::{collections::VecDeque, sync::{Arc, Mutex, RwLock, mpsc::{Sender, channel}}, thread};
2
3
use opus::{Channels, Decoder};
4
5
use crate::{MONO_20MS, SAMPLE_RATE};
6
7
pub struct VoiceChatDecoder{
8
+
stream_in: Sender<Vec<u8>>,
9
+
last_rms: Arc<RwLock<f32>>
10
}
11
12
impl VoiceChatDecoder{
···
14
let mut decoder = Decoder::new(SAMPLE_RATE as u32, Channels::Mono).unwrap();
15
let ( stream_in, stream_out ) = channel();
16
17
+
let set_rms = Arc::new(RwLock::new(0.0));
18
+
let set_rms_1 = set_rms.clone();
19
+
20
thread::spawn(move || {
21
let mut buffer = [0.0; MONO_20MS];
22
···
24
let packet: Vec<u8> = stream_out.recv().unwrap();
25
decoder.decode_float(&packet, &mut buffer, false).unwrap();
26
27
+
let mut total = 0.0;
28
+
for sample in buffer{ total += sample.powi(2) }
29
+
*set_rms.write().unwrap() = ( total / buffer.len() as f32 ).sqrt();
30
+
31
let mut voice = queue.lock().unwrap();
32
for sample in buffer{ voice.push_back(sample); }
33
}
34
});
35
36
+
Self {
37
+
stream_in,
38
+
last_rms: set_rms_1
39
+
}
40
}
41
42
pub fn decode( &self, packet: Vec<u8> ){
43
self.stream_in.send(packet).unwrap();
44
+
}
45
+
46
+
pub fn get_last_rms( &self ) -> f32{
47
+
*self.last_rms.read().unwrap()
48
}
49
}
+35
-4
audio/src/voice/microphone.rs
+35
-4
audio/src/voice/microphone.rs
···
1
-
use std::{env, net::{ToSocketAddrs, UdpSocket}, sync::{Arc, Mutex}};
2
3
use bevy::ecs::component::Component;
4
use cpal::{BufferSize, SampleRate, Stream, StreamConfig, traits::{DeviceTrait, HostTrait, StreamTrait}};
···
11
pub struct VoiceChatMicrophone{
12
stream: Option<Stream>,
13
udp: Option<UdpSocket>,
14
-
muted: Arc<Mutex<bool>>
15
}
16
17
impl VoiceChatMicrophone{
···
19
Self {
20
stream: None,
21
udp: Some(socket),
22
-
muted: Arc::new(Mutex::new(false))
23
}
24
}
25
···
33
let mut encoder = Encoder::new(SAMPLE_RATE as u32, Channels::Mono, Application::Voip)?;
34
35
let host = cpal::default_host();
36
-
let mic = host.default_input_device().unwrap();
37
38
let mut output = [0; 512];
39
···
45
46
let addr = env::var("HOST")?.to_socket_addrs()?.nth(0).unwrap();
47
48
let stream = mic.build_input_stream(
49
&StreamConfig {
50
channels: 1,
···
63
64
if buffer_indx >= MONO_20MS{
65
buffer_indx = 0;
66
67
let len = encoder.encode(&buffer, &mut output).unwrap();
68
let buf_to_send = output[0..len].to_vec();
···
86
self.stream = Some(stream);
87
88
Ok(())
89
}
90
}
···
1
+
use std::{env, net::{ToSocketAddrs, UdpSocket}, sync::{Arc, Mutex, RwLock}};
2
3
use bevy::ecs::component::Component;
4
use cpal::{BufferSize, SampleRate, Stream, StreamConfig, traits::{DeviceTrait, HostTrait, StreamTrait}};
···
11
pub struct VoiceChatMicrophone{
12
stream: Option<Stream>,
13
udp: Option<UdpSocket>,
14
+
muted: Arc<Mutex<bool>>,
15
+
last_rms: Arc<RwLock<isize>>
16
}
17
18
impl VoiceChatMicrophone{
···
20
Self {
21
stream: None,
22
udp: Some(socket),
23
+
muted: Arc::new(Mutex::new(false)), // TODO: Default to muted
24
+
last_rms: Arc::new(RwLock::new(0))
25
}
26
}
27
···
35
let mut encoder = Encoder::new(SAMPLE_RATE as u32, Channels::Mono, Application::Voip)?;
36
37
let host = cpal::default_host();
38
+
39
+
let mut i = 0;
40
+
let devices = host.input_devices().unwrap();
41
+
for device in devices{
42
+
println!("{}) {:?}", i, device.name());
43
+
i += 1;
44
+
}
45
+
46
+
let mut devices = host.input_devices().unwrap();
47
+
let mic = if let Ok(device_index) = env::var("MIC_INDEX"){
48
+
devices.nth(device_index.parse()?).unwrap()
49
+
} else{
50
+
host.default_input_device().unwrap()
51
+
};
52
+
53
+
println!("Using Device: {:?}", mic.name());
54
55
let mut output = [0; 512];
56
···
62
63
let addr = env::var("HOST")?.to_socket_addrs()?.nth(0).unwrap();
64
65
+
for conf in mic.supported_input_configs().unwrap(){
66
+
println!("{} {:?} {} {:?}", conf.channels(), conf.buffer_size(), conf.sample_format(), conf.with_max_sample_rate());
67
+
}
68
+
69
+
let set_rms = self.last_rms.clone();
70
+
71
let stream = mic.build_input_stream(
72
&StreamConfig {
73
channels: 1,
···
86
87
if buffer_indx >= MONO_20MS{
88
buffer_indx = 0;
89
+
90
+
let mut total = 0;
91
+
for sample in buffer{ total += (sample as isize).pow(2) }
92
+
*set_rms.write().unwrap() = ( total / buffer.len() as isize ).isqrt();
93
94
let len = encoder.encode(&buffer, &mut output).unwrap();
95
let buf_to_send = output[0..len].to_vec();
···
113
self.stream = Some(stream);
114
115
Ok(())
116
+
}
117
+
118
+
pub fn get_rms_of_last_packet( &self ) -> f32{
119
+
*self.last_rms.read().unwrap() as f32 / i16::MAX as f32
120
}
121
}
+60
client/src/components/debug_camera.rs
+60
client/src/components/debug_camera.rs
···
1
use std::f32::consts::PI;
2
3
use bevy::{ input::mouse::MouseMotion, prelude::* };
4
5
#[derive(Component)]
6
pub struct DebugCamera{
···
25
keys: Res<ButtonInput<KeyCode>>,
26
mouse_buttons: Res<ButtonInput<MouseButton>>,
27
mut mouse_motion: MessageReader<MouseMotion>,
28
){
29
let mut delta_time = time.delta_secs();
30
if keys.pressed(KeyCode::ShiftLeft){ delta_time *= 2.0; }
31
···
63
let dir = -transform.up();
64
transform.translation += dir * delta_time;
65
}
66
}
···
1
use std::f32::consts::PI;
2
3
use bevy::{ input::mouse::MouseMotion, prelude::* };
4
+
use felix_audio::voice::microphone::VoiceChatMicrophone;
5
+
6
+
use crate::net::connection::Connection;
7
8
#[derive(Component)]
9
pub struct DebugCamera{
···
28
keys: Res<ButtonInput<KeyCode>>,
29
mouse_buttons: Res<ButtonInput<MouseButton>>,
30
mut mouse_motion: MessageReader<MouseMotion>,
31
+
32
+
// Debug Text
33
+
mut debug_text: Query<(&mut Text, &DebugText)>,
34
+
voice: Query<&VoiceChatMicrophone>,
35
+
networking: Query<&Connection>,
36
){
37
+
let net_manager = networking.single().unwrap();
38
+
39
let mut delta_time = time.delta_secs();
40
if keys.pressed(KeyCode::ShiftLeft){ delta_time *= 2.0; }
41
···
73
let dir = -transform.up();
74
transform.translation += dir * delta_time;
75
}
76
+
77
+
let mut remote_rms = "".to_owned();
78
+
for id in net_manager.get_remote_player_voice_ids(){
79
+
remote_rms += format!("{}: {:.4}\n", id, net_manager.get_remote_player_voice_rms(&id)).as_str();
80
+
}
81
+
82
+
let rms = if let Ok(mic) = voice.single(){
83
+
mic.get_rms_of_last_packet()
84
+
} else{
85
+
-1.0
86
+
};
87
+
88
+
let ( mut text, _ ) = debug_text.single_mut().unwrap();
89
+
text.0 = format!(
90
+
"Microphone RMS: {:.4}
91
+
{}Position: {:.2} {:.2} {:.2}
92
+
Rotation: {:.2} {:.2} {:.2} {:.2}",
93
+
rms,
94
+
95
+
remote_rms,
96
+
97
+
transform.translation.x,
98
+
transform.translation.y,
99
+
transform.translation.z,
100
+
101
+
transform.rotation.x,
102
+
transform.rotation.y,
103
+
transform.rotation.z,
104
+
transform.rotation.w
105
+
);
106
+
}
107
+
108
+
#[derive(Component)]
109
+
pub struct DebugText;
110
+
111
+
pub fn setup(
112
+
mut commands: Commands
113
+
){
114
+
commands.spawn((
115
+
Node {
116
+
position_type: PositionType::Absolute,
117
+
bottom: px(5.0),
118
+
right: px(5.0),
119
+
..default()
120
+
},
121
+
Text::new("Here is some text"),
122
+
TextColor(Color::WHITE),
123
+
TextLayout::new_with_justify(Justify::Right),
124
+
DebugText
125
+
));
126
}
+1
-1
client/src/components/network_interface.rs
+1
-1
client/src/components/network_interface.rs
+8
-4
client/src/main.rs
+8
-4
client/src/main.rs
···
8
mod net;
9
10
fn main() {
11
-
dotenvy::dotenv().unwrap();
12
13
App::new()
14
.add_plugins((
···
17
))
18
.add_systems(Startup, setup)
19
.add_systems(Startup, move | mut commands: Commands |{
20
-
let ( comp, voice ) = net::handle_net().expect("Network Module Failed.");
21
-
22
commands.spawn(comp);
23
-
commands.spawn(voice::init_microphone(voice).expect("Failed to start microphone."));
24
})
25
.add_systems(Update, debug_camera::update)
26
.add_systems(Update, remote_player::update)
27
.add_systems(FixedUpdate, network_interface::fixed_update)
28
.run();
···
8
mod net;
9
10
fn main() {
11
+
if let Err(err) = dotenvy::dotenv(){ println!("[WARN] .ENV failed loading {:#?}", err); }
12
13
App::new()
14
.add_plugins((
···
17
))
18
.add_systems(Startup, setup)
19
.add_systems(Startup, move | mut commands: Commands |{
20
+
let ( comp, voice ) = net::handle_net().expect("Network Module Failed");
21
commands.spawn(comp);
22
+
23
+
match voice::init_microphone(voice){
24
+
Ok(voice) => { commands.spawn(voice); },
25
+
Err(err) => println!("[WARN] Failed to start microphone: {}", err)
26
+
}
27
})
28
.add_systems(Update, debug_camera::update)
29
+
.add_systems(Startup, debug_camera::setup)
30
.add_systems(Update, remote_player::update)
31
.add_systems(FixedUpdate, network_interface::fixed_update)
32
.run();
+52
-14
client/src/net/connection.rs
+52
-14
client/src/net/connection.rs
···
1
-
use std::{collections::{HashMap, VecDeque}, io::{Read, Write}, net::{SocketAddr, TcpStream, UdpSocket}, sync::{Arc, Mutex, RwLock}, thread};
2
use bevy::ecs::component::Component;
3
use felix_audio::voice::decoder::VoiceChatDecoder;
4
use tokio::sync::broadcast::{self, Receiver, Sender};
···
14
udp: UdpSocket,
15
udp_server_address: SocketAddr,
16
17
net_recv: Receiver<NetClientCommand>,
18
19
voice_queues: Arc<RwLock<HashMap<String, VoiceChatDecoder>>>,
20
-
pub id: String
21
}
22
23
impl Connection{
24
pub fn new( stream: TcpStream, udp: UdpSocket, udp_server_address: SocketAddr ) -> Self{
25
let ( event_sender, event_recv ) = broadcast::channel(32);
26
27
let mut conn = Self {
28
tcp: stream,
···
30
udp,
31
udp_server_address,
32
33
net_recv: event_recv,
34
35
voice_queues: Arc::new(RwLock::new(HashMap::new())),
36
-
id: "".to_owned()
37
};
38
39
-
conn.start_listener_thread(event_sender).unwrap();
40
41
let packet = NotifyConnectionInfo { id: conn.id.clone() };
42
conn.send_reliable(packet).unwrap();
···
44
conn
45
}
46
47
-
fn start_listener_thread(&self, cmd: Sender<NetClientCommand>) -> anyhow::Result<()>{
48
let mut tcp = self.tcp.try_clone()?;
49
let udp = self.udp.try_clone()?;
50
···
54
let srv_addr = self.udp_server_address.clone();
55
let voice_queues = self.voice_queues.clone();
56
57
thread::spawn(move || { // UDP RECV THREAD
58
let mut buf = [0; 1024];
59
60
while let Ok((length, addr)) = udp_1.recv_from(&mut buf){
61
if addr != srv_addr{ continue; }
62
63
let mut msg: Buffer = (&buf[0..length]).into();
64
65
while msg.left() > 0{
66
let packet = packet::parse(&mut msg);
67
-
cmd_1.send(NetClientCommand::RecvPacket(packet)).unwrap();
68
}
69
}
70
});
···
74
75
while let Ok(length) = tcp.read(&mut buf){
76
if length == 0 { break; }
77
78
let mut msg: Buffer = (&buf[0..length]).into();
79
···
87
let packet = LinkUDP { id: info.id };
88
let packet: Vec<_> = packet.to_buf().into();
89
90
-
udp.send_to(&packet, "127.0.0.1:2603").unwrap();
91
-
},
92
-
PacketTypes::PlayerVoicePacket(packet) => {
93
-
let voices = voice_queues.read().unwrap();
94
-
if let Some(decoder) = voices.get(&packet.id){
95
-
decoder.decode(packet.packet); }
96
},
97
_ => {
98
cmd.send(NetClientCommand::RecvPacket(packet)).unwrap();
···
107
Ok(())
108
}
109
110
-
pub fn start_listening_for_player_voice( &mut self, id: &String ) -> Arc<Mutex<VecDeque<f32>>>{
111
let voice_queue = Arc::new(Mutex::new(VecDeque::new()));
112
let decoder = VoiceChatDecoder::new(voice_queue.clone());
113
···
117
voice_queue
118
}
119
120
-
pub fn stop_listening_for_player_voice( &mut self, id: &String ){
121
let mut voices = self.voice_queues.write().unwrap();
122
voices.remove(id);
123
}
···
138
self.udp.send_to(&buf, self.udp_server_address)?;
139
140
Ok(())
141
}
142
}
···
1
+
use std::{collections::{HashMap, VecDeque}, io::{Read, Write}, net::{Shutdown, SocketAddr, TcpStream, UdpSocket}, sync::{Arc, Mutex, RwLock}, thread};
2
use bevy::ecs::component::Component;
3
use felix_audio::voice::decoder::VoiceChatDecoder;
4
use tokio::sync::broadcast::{self, Receiver, Sender};
···
14
udp: UdpSocket,
15
udp_server_address: SocketAddr,
16
17
+
net_send: Sender<NetClientCommand>,
18
net_recv: Receiver<NetClientCommand>,
19
20
voice_queues: Arc<RwLock<HashMap<String, VoiceChatDecoder>>>,
21
+
pub id: String,
22
+
23
+
killed_signal: broadcast::Sender<()>
24
}
25
26
impl Connection{
27
pub fn new( stream: TcpStream, udp: UdpSocket, udp_server_address: SocketAddr ) -> Self{
28
let ( event_sender, event_recv ) = broadcast::channel(32);
29
+
let ( killed_signal_send, killed_signal ) = broadcast::channel(32);
30
31
let mut conn = Self {
32
tcp: stream,
···
34
udp,
35
udp_server_address,
36
37
+
net_send: event_sender.clone(),
38
net_recv: event_recv,
39
40
voice_queues: Arc::new(RwLock::new(HashMap::new())),
41
+
id: "".to_owned(),
42
+
43
+
killed_signal: killed_signal_send
44
};
45
46
+
conn.start_listener_thread(event_sender, killed_signal).unwrap();
47
48
let packet = NotifyConnectionInfo { id: conn.id.clone() };
49
conn.send_reliable(packet).unwrap();
···
51
conn
52
}
53
54
+
fn start_listener_thread(&self, cmd: Sender<NetClientCommand>, mut signal: Receiver<()>) -> anyhow::Result<()>{
55
let mut tcp = self.tcp.try_clone()?;
56
let udp = self.udp.try_clone()?;
57
···
61
let srv_addr = self.udp_server_address.clone();
62
let voice_queues = self.voice_queues.clone();
63
64
+
let mut signal_1 = signal.resubscribe();
65
+
66
thread::spawn(move || { // UDP RECV THREAD
67
let mut buf = [0; 1024];
68
69
while let Ok((length, addr)) = udp_1.recv_from(&mut buf){
70
if addr != srv_addr{ continue; }
71
+
if signal_1.try_recv().is_ok(){ break; }
72
73
let mut msg: Buffer = (&buf[0..length]).into();
74
75
while msg.left() > 0{
76
let packet = packet::parse(&mut msg);
77
+
78
+
match packet{
79
+
PacketTypes::PlayerVoicePacket(packet) => {
80
+
let voices = voice_queues.try_read().unwrap();
81
+
if let Some(decoder) = voices.get(&packet.id){
82
+
decoder.decode(packet.packet); }
83
+
},
84
+
_ => {
85
+
cmd_1.send(NetClientCommand::RecvPacket(packet)).unwrap();
86
+
}
87
+
}
88
}
89
}
90
});
···
94
95
while let Ok(length) = tcp.read(&mut buf){
96
if length == 0 { break; }
97
+
if signal.try_recv().is_ok(){ break; }
98
99
let mut msg: Buffer = (&buf[0..length]).into();
100
···
108
let packet = LinkUDP { id: info.id };
109
let packet: Vec<_> = packet.to_buf().into();
110
111
+
udp.send_to(&packet, srv_addr).unwrap();
112
},
113
_ => {
114
cmd.send(NetClientCommand::RecvPacket(packet)).unwrap();
···
123
Ok(())
124
}
125
126
+
pub fn get_remote_player_voice_ids( &self ) -> Vec<String>{
127
+
let voices = self.voice_queues.read().unwrap();
128
+
voices.iter().map(| x | x.0.clone()).collect()
129
+
}
130
+
131
+
pub fn get_remote_player_voice_rms( &self, id: &String ) -> f32{
132
+
let voices = self.voice_queues.read().unwrap();
133
+
let decoder = voices.get(id).unwrap();
134
+
135
+
decoder.get_last_rms()
136
+
}
137
+
138
+
pub fn start_listening_for_player_voice( &self, id: &String ) -> Arc<Mutex<VecDeque<f32>>>{
139
let voice_queue = Arc::new(Mutex::new(VecDeque::new()));
140
let decoder = VoiceChatDecoder::new(voice_queue.clone());
141
···
145
voice_queue
146
}
147
148
+
pub fn stop_listening_for_player_voice( &self, id: &String ){
149
let mut voices = self.voice_queues.write().unwrap();
150
voices.remove(id);
151
}
···
166
self.udp.send_to(&buf, self.udp_server_address)?;
167
168
Ok(())
169
+
}
170
+
}
171
+
172
+
impl Drop for Connection{
173
+
fn drop(&mut self) {
174
+
println!("Killing connection to: {}", self.udp_server_address);
175
+
self.net_send.send(NetClientCommand::Disconnected).unwrap();
176
+
177
+
self.killed_signal.send(()).unwrap();
178
+
self.tcp.shutdown(Shutdown::Both).unwrap();
179
}
180
}
+8
-2
client/src/setup.rs
+8
-2
client/src/setup.rs
···
1
use bevy::prelude::*;
2
use felix_audio::FelixAudioListener;
3
4
-
use crate::debug_camera;
5
6
pub fn setup(
7
mut commands: Commands,
8
mut meshes: ResMut<Assets<Mesh>>,
9
mut materials: ResMut<Assets<StandardMaterial>>
10
){
11
commands.spawn((
12
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
13
MeshMaterial3d(materials.add(Color::WHITE)),
···
33
));
34
35
commands.spawn((
36
-
debug_camera::DebugCamera::default(),
37
Camera3d::default(),
38
Transform::from_xyz(0.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
39
FelixAudioListener
···
1
use bevy::prelude::*;
2
use felix_audio::FelixAudioListener;
3
4
+
use crate::components::debug_camera::DebugCamera;
5
6
pub fn setup(
7
mut commands: Commands,
8
mut meshes: ResMut<Assets<Mesh>>,
9
mut materials: ResMut<Assets<StandardMaterial>>
10
){
11
+
// TODO: World loading from server
12
+
13
+
// TODO: World loading format? Could build an asset bundle parser?
14
+
15
+
// TODO: UI and Menus
16
+
17
commands.spawn((
18
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
19
MeshMaterial3d(materials.add(Color::WHITE)),
···
39
));
40
41
commands.spawn((
42
+
DebugCamera::default(), // TODO: Build a proper player controller
43
Camera3d::default(),
44
Transform::from_xyz(0.0, 0.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
45
FelixAudioListener
-4
server/src/net/connection.rs
-4
server/src/net/connection.rs
···
74
self.position = packet.position;
75
self.rotation = packet.rotation;
76
},
77
-
PacketTypes::PlayerVoicePacket(mut voice) => {
78
-
voice.id = self.id.clone(); // NOTE: See "audio/src/voice/microphone.rs:71"
79
-
self.main_thread_sender.send(NetServerCommand::BroadcastVoice(voice)).unwrap();
80
-
},
81
_ => {}
82
}
83
+19
-10
server/src/net/mod.rs
+19
-10
server/src/net/mod.rs
···
1
use std::{collections::HashMap, env, net::{SocketAddr, TcpListener, TcpStream, UdpSocket}, thread, time::Duration};
2
3
-
use felix_net::{buffer::Buffer, packet::{self, PacketTypes}, packets::{player_join_packet::PlayerJoinPacket, player_leave_packet::PlayerLeavePacket, player_list_packet::PlayerListPacket, player_voice_packet::PlayerVoicePacket, update_clients_positions::UpdateClientsPositions}};
4
5
use crate::net::connection::Connection;
6
···
13
SendOverUDP(Vec<u8>, SocketAddr),
14
RecvOverUDP(SocketAddr, PacketTypes),
15
RecvOverTCP(String, PacketTypes),
16
-
BroadcastVoice(PlayerVoicePacket),
17
BroadcastPlayerPositions
18
}
19
20
pub fn handle_net() -> anyhow::Result<()>{
21
let port = env::var("HOST_PORT")?;
22
23
let tcp_listener = TcpListener::bind(format!("0.0.0.0:{}", port))?;
···
113
},
114
NetServerCommand::RecvOverUDP(addr, packet) => {
115
if let Some(conn_id) = connections_by_address.get(&addr){
116
-
let conn = connections.get_mut(conn_id).unwrap();
117
-
conn.recv_packet(packet)?;
118
}
119
},
120
NetServerCommand::RecvOverTCP(conn_id, packet) => {
···
130
131
for (_, conn) in &mut connections{
132
conn.try_send_unreliable(packet.clone())?; }
133
-
},
134
-
NetServerCommand::BroadcastVoice(packet) => {
135
-
for ( remote_id, conn ) in &mut connections{
136
-
if remote_id == &packet.id { continue; }
137
-
conn.try_send_unreliable(packet.clone())?;
138
-
}
139
}
140
}
141
}
···
1
use std::{collections::HashMap, env, net::{SocketAddr, TcpListener, TcpStream, UdpSocket}, thread, time::Duration};
2
3
+
use felix_net::{buffer::Buffer, packet::{self, PacketTypes}, packets::{player_join_packet::PlayerJoinPacket, player_leave_packet::PlayerLeavePacket, player_list_packet::PlayerListPacket, update_clients_positions::UpdateClientsPositions}};
4
5
use crate::net::connection::Connection;
6
···
13
SendOverUDP(Vec<u8>, SocketAddr),
14
RecvOverUDP(SocketAddr, PacketTypes),
15
RecvOverTCP(String, PacketTypes),
16
BroadcastPlayerPositions
17
}
18
19
pub fn handle_net() -> anyhow::Result<()>{
20
+
// TODO: Multiple instances
21
+
// Need to decide if i want to run each instance on a seperate thread
22
+
23
let port = env::var("HOST_PORT")?;
24
25
let tcp_listener = TcpListener::bind(format!("0.0.0.0:{}", port))?;
···
115
},
116
NetServerCommand::RecvOverUDP(addr, packet) => {
117
if let Some(conn_id) = connections_by_address.get(&addr){
118
+
match packet {
119
+
PacketTypes::PlayerVoicePacket(mut voice) => { // Keep voice stuff in one thread to avoid copying a lot of data all over the place
120
+
voice.id = conn_id.clone(); // NOTE: See "audio/src/voice/microphone.rs:71"
121
+
122
+
for ( remote_id, conn ) in &mut connections{
123
+
if remote_id == &voice.id { continue; }
124
+
conn.try_send_unreliable(voice.clone())?;
125
+
}
126
+
},
127
+
_ => {
128
+
let conn = connections.get_mut(conn_id).unwrap();
129
+
conn.recv_packet(packet)?;
130
+
}
131
+
}
132
+
133
}
134
},
135
NetServerCommand::RecvOverTCP(conn_id, packet) => {
···
145
146
for (_, conn) in &mut connections{
147
conn.try_send_unreliable(packet.clone())?; }
148
}
149
}
150
}