+43
Cargo.lock
+43
Cargo.lock
···
315
315
]
316
316
317
317
[[package]]
318
+
name = "audiopus_sys"
319
+
version = "0.2.2"
320
+
source = "registry+https://github.com/rust-lang/crates.io-index"
321
+
checksum = "62314a1546a2064e033665d658e88c620a62904be945f8147e6b16c3db9f8651"
322
+
dependencies = [
323
+
"cmake",
324
+
"log",
325
+
"pkg-config",
326
+
]
327
+
328
+
[[package]]
318
329
name = "autocfg"
319
330
version = "1.5.0"
320
331
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1743
1754
]
1744
1755
1745
1756
[[package]]
1757
+
name = "cmake"
1758
+
version = "0.1.57"
1759
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1760
+
checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d"
1761
+
dependencies = [
1762
+
"cc",
1763
+
]
1764
+
1765
+
[[package]]
1746
1766
name = "codespan-reporting"
1747
1767
version = "0.12.0"
1748
1768
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2290
2310
"anyhow",
2291
2311
"bevy",
2292
2312
"cpal 0.16.0",
2313
+
"felix-net",
2293
2314
"hound",
2294
2315
"kira",
2316
+
"opus",
2295
2317
]
2296
2318
2297
2319
[[package]]
···
2323
2345
"bevy_math",
2324
2346
"dotenvy",
2325
2347
"felix-net",
2348
+
"kanal",
2326
2349
"nanoid",
2327
2350
]
2328
2351
···
2897
2920
dependencies = [
2898
2921
"once_cell",
2899
2922
"wasm-bindgen",
2923
+
]
2924
+
2925
+
[[package]]
2926
+
name = "kanal"
2927
+
version = "0.1.1"
2928
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2929
+
checksum = "9e3953adf0cd667798b396c2fa13552d6d9b3269d7dd1154c4c416442d1ff574"
2930
+
dependencies = [
2931
+
"futures-core",
2932
+
"lock_api",
2900
2933
]
2901
2934
2902
2935
[[package]]
···
3665
3698
version = "1.21.3"
3666
3699
source = "registry+https://github.com/rust-lang/crates.io-index"
3667
3700
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
3701
+
3702
+
[[package]]
3703
+
name = "opus"
3704
+
version = "0.3.0"
3705
+
source = "registry+https://github.com/rust-lang/crates.io-index"
3706
+
checksum = "6526409b274a7e98e55ff59d96aafd38e6cd34d46b7dbbc32ce126dffcd75e8e"
3707
+
dependencies = [
3708
+
"audiopus_sys",
3709
+
"libc",
3710
+
]
3668
3711
3669
3712
[[package]]
3670
3713
name = "orbclient"
+2
audio/Cargo.toml
+2
audio/Cargo.toml
+10
-11
audio/src/lib.rs
+10
-11
audio/src/lib.rs
···
4
4
5
5
use crate::source::FelixAudioSource;
6
6
7
+
pub const SAMPLE_RATE: usize = 48_000;
8
+
pub const BUFFER_SIZE: usize = 512;
9
+
10
+
const MONO_20MS: usize = SAMPLE_RATE * 20 / 1000;
11
+
7
12
pub mod source;
8
13
pub mod utils;
14
+
pub mod voice;
9
15
10
-
fn update_listener_transform(
16
+
fn update_audio_system(
11
17
mut audio_system: Query<&mut FelixAudioComponent>,
12
-
listener: Query<(&FelixAudioListener, &Transform)>
18
+
listener: Query<(&FelixAudioListener, &Transform)>,
19
+
sources: Query<(&mut FelixAudioSource, &Transform)>,
13
20
){
14
21
let mut audio_system = audio_system.single_mut().expect("Cannot find FelixAudioComponent, has audio system been initialised?");
15
22
let ( _, listener_transform ) = listener.single().expect("Cannot find FelixAudioListener.");
16
23
17
24
audio_system.main_listener.set_position(listener_transform.translation, Tween::default());
18
25
audio_system.main_listener.set_orientation(listener_transform.rotation, Tween::default());
19
-
}
20
-
21
-
fn update_audio_sources(
22
-
mut audio_system: Query<&mut FelixAudioComponent>,
23
-
sources: Query<(&mut FelixAudioSource, &Transform)>,
24
-
){
25
-
let mut audio_system = audio_system.single_mut().expect("Cannot find FelixAudioComponent, has audio system been initialised?");
26
26
27
27
for ( mut source, transform ) in sources{
28
28
if source.needs_init(){
···
65
65
commands.spawn(handle);
66
66
});
67
67
68
-
app.add_systems(Update, update_listener_transform);
69
-
app.add_systems(Update, update_audio_sources);
68
+
app.add_systems(Update, update_audio_system);
70
69
}
71
70
}
+34
audio/src/voice/decoder.rs
+34
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{
12
+
pub fn new( queue: Arc<Mutex<VecDeque<f32>>> ) -> Self{
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
+
19
+
loop {
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
+
}
+90
audio/src/voice/microphone.rs
+90
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}};
5
+
use felix_net::{packet::Packet, packets::player_voice_packet::PlayerVoicePacket};
6
+
use opus::{Application, Channels, Encoder};
7
+
8
+
use crate::{BUFFER_SIZE, MONO_20MS, SAMPLE_RATE};
9
+
10
+
#[derive(Component)]
11
+
pub struct VoiceChatMicrophone{
12
+
stream: Option<Stream>,
13
+
udp: Option<UdpSocket>,
14
+
muted: Arc<Mutex<bool>>
15
+
}
16
+
17
+
impl VoiceChatMicrophone{
18
+
pub fn new( socket: UdpSocket ) -> Self{
19
+
Self {
20
+
stream: None,
21
+
udp: Some(socket),
22
+
muted: Arc::new(Mutex::new(false))
23
+
}
24
+
}
25
+
26
+
pub fn muted( &mut self, muted: bool ){
27
+
*self.muted.lock().unwrap() = muted;
28
+
}
29
+
30
+
pub fn start_stream( &mut self ) -> anyhow::Result<()>{
31
+
if let Some(stream) = &mut self.stream{ stream.pause().unwrap() }
32
+
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
+
40
+
let mut buffer_indx = 0;
41
+
let mut buffer = [0; MONO_20MS];
42
+
43
+
let muted = self.muted.clone();
44
+
let udp = self.udp.take().unwrap();
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,
51
+
buffer_size: BufferSize::Fixed(BUFFER_SIZE as u32),
52
+
sample_rate: SampleRate(SAMPLE_RATE as u32)
53
+
},
54
+
move | data: &[ i16 ], _ | {
55
+
let muted = *muted.lock().unwrap();
56
+
57
+
if muted{
58
+
buffer_indx = 0;
59
+
} else{
60
+
for i in 0..data.len(){
61
+
buffer[buffer_indx] = data[i];
62
+
buffer_indx += 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();
69
+
70
+
let packet = PlayerVoicePacket {
71
+
id: "".into(), // NOTE: I know this kinda seems stupid but it's easier for me to get the player id on the server so imma just make the server fill this in.
72
+
packet: buf_to_send
73
+
};
74
+
75
+
let packet: Vec<u8> = packet.to_buf().into();
76
+
udp.send_to(&packet, addr).unwrap();
77
+
}
78
+
}
79
+
}
80
+
},
81
+
| err | panic!("{err}"),
82
+
None
83
+
).unwrap();
84
+
85
+
stream.play().unwrap();
86
+
self.stream = Some(stream);
87
+
88
+
Ok(())
89
+
}
90
+
}
+13
audio/src/voice/mod.rs
+13
audio/src/voice/mod.rs
···
1
+
use std::net::UdpSocket;
2
+
3
+
use crate::voice::microphone::VoiceChatMicrophone;
4
+
5
+
pub mod decoder;
6
+
pub mod microphone;
7
+
8
+
pub fn init_microphone( socket: UdpSocket ) -> anyhow::Result<VoiceChatMicrophone>{
9
+
let mut handle = VoiceChatMicrophone::new(socket);
10
+
handle.start_stream()?;
11
+
12
+
Ok(handle)
13
+
}
client/out.wav
client/out.wav
This is a binary file and will not be displayed.
+18
-4
client/src/components/network_interface.rs
+18
-4
client/src/components/network_interface.rs
···
1
1
use std::collections::HashMap;
2
2
3
3
use bevy::prelude::*;
4
+
use felix_audio::{SAMPLE_RATE, source::{FelixAudioSource, stream_source::StreamAudioSource}};
4
5
use felix_net::{packet::PacketTypes, packets::update_server_position::UpdateServerPositions};
5
6
6
7
use crate::{debug_camera::DebugCamera, net::{NetClientCommand, connection::Connection}, remote_player::RemotePlayer};
7
8
8
9
pub fn fixed_update(
9
10
mut query: Query<(&mut DebugCamera, &mut Transform)>,
11
+
10
12
mut networking: Query<&mut Connection>,
11
13
12
14
mut commands: Commands,
···
24
26
};
25
27
26
28
net_manager.try_send_unreliable(update_pos_packet).unwrap();
27
-
28
29
29
30
if let Ok(ev) = net_manager.recv_event(){
30
31
match ev{
···
37
38
NetClientCommand::RecvPacket(packet) => {
38
39
match packet{
39
40
PacketTypes::PlayerJoinPacket(packet) => {
40
-
join_players(vec![packet.id], &mut commands, &mut meshes, &mut materials);
41
+
join_players(vec![packet.id], &mut commands, &mut meshes, &mut materials, &mut net_manager);
41
42
}
42
43
PacketTypes::PlayerListPacket(packet) => {
43
-
join_players(packet.ids, &mut commands, &mut meshes, &mut materials);
44
+
join_players(packet.ids, &mut commands, &mut meshes, &mut materials, &mut net_manager);
44
45
}
45
46
PacketTypes::PlayerLeavePacket(packet) => {
46
47
leave_player(packet.id, &mut commands, players);
···
71
72
commands: &mut Commands,
72
73
meshes: &mut ResMut<Assets<Mesh>>,
73
74
materials: &mut ResMut<Assets<StandardMaterial>>,
75
+
76
+
net_manager: &mut Connection
74
77
){
75
78
for id in players{
79
+
let listener = net_manager.start_listening_for_player_voice(&id);
80
+
76
81
commands.spawn((
77
82
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
78
83
MeshMaterial3d(materials.add(Color::WHITE)),
79
84
Transform::from_xyz(0.0, 0.0, 0.0),
80
-
RemotePlayer { id, ..Default::default() }
85
+
RemotePlayer { id, ..Default::default() },
86
+
FelixAudioSource::from(StreamAudioSource::new(SAMPLE_RATE, move | len | {
87
+
let mut buf = vec![0.0; len];
88
+
let mut lock = listener.lock().unwrap();
89
+
90
+
for i in 0..buf.len(){
91
+
buf[i] = lock.pop_front().unwrap(); }
92
+
93
+
buf
94
+
}))
81
95
));
82
96
}
83
97
}
+5
-2
client/src/main.rs
+5
-2
client/src/main.rs
···
1
1
use bevy::{DefaultPlugins, app::{App, FixedUpdate, Startup, Update}, ecs::system::Commands};
2
-
use felix_audio::FelixAudio;
2
+
use felix_audio::{FelixAudio, voice};
3
3
4
4
use crate::{components::{debug_camera, network_interface, remote_player}, setup::setup};
5
5
···
17
17
))
18
18
.add_systems(Startup, setup)
19
19
.add_systems(Startup, move | mut commands: Commands |{
20
-
commands.spawn(net::handle_net().expect("Network Module Failed."));
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."));
21
24
})
22
25
.add_systems(Update, debug_camera::update)
23
26
.add_systems(Update, remote_player::update)
+21
-3
client/src/net/connection.rs
+21
-3
client/src/net/connection.rs
···
1
-
use std::{io::{Read, Write}, net::{SocketAddr, TcpStream, UdpSocket}, thread};
1
+
use std::{collections::{HashMap, VecDeque}, io::{Read, Write}, net::{SocketAddr, TcpStream, UdpSocket}, sync::{Arc, Mutex, RwLock}, thread};
2
2
use bevy::ecs::component::Component;
3
+
use felix_audio::voice::decoder::VoiceChatDecoder;
3
4
use tokio::sync::broadcast::{self, Receiver, Sender};
4
5
5
6
use felix_net::{buffer::Buffer, packet::{self, Packet, PacketTypes}, packets::{link_udp::LinkUDP, notify_connection_info::NotifyConnectionInfo}};
6
7
7
8
use crate::net::NetClientCommand;
8
9
9
-
10
-
#[derive(Component, Debug)]
10
+
#[derive(Component)]
11
11
pub struct Connection{
12
12
tcp: TcpStream,
13
13
···
16
16
17
17
net_recv: Receiver<NetClientCommand>,
18
18
19
+
voice_queues: Arc<RwLock<HashMap<String, VoiceChatDecoder>>>,
19
20
pub id: String
20
21
}
21
22
···
31
32
32
33
net_recv: event_recv,
33
34
35
+
voice_queues: Arc::new(RwLock::new(HashMap::new())),
34
36
id: "".to_owned()
35
37
};
36
38
···
50
52
let cmd_1 = cmd.clone();
51
53
52
54
let srv_addr = self.udp_server_address.clone();
55
+
let voice_queues = self.voice_queues.clone();
53
56
54
57
thread::spawn(move || { // UDP RECV THREAD
55
58
let mut buf = [0; 1024];
···
86
89
87
90
udp.send_to(&packet, "127.0.0.1:2603").unwrap();
88
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
+
},
89
97
_ => {
90
98
cmd.send(NetClientCommand::RecvPacket(packet)).unwrap();
91
99
}
···
97
105
});
98
106
99
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
+
114
+
let mut voices = self.voice_queues.write().unwrap();
115
+
voices.insert(id.clone(), decoder);
116
+
117
+
voice_queue
100
118
}
101
119
102
120
pub fn recv_event(&mut self) -> anyhow::Result<NetClientCommand>{
+3
-3
client/src/net/mod.rs
+3
-3
client/src/net/mod.rs
···
14
14
RecvPacket(PacketTypes)
15
15
}
16
16
17
-
pub fn handle_net() -> anyhow::Result<Connection>{
17
+
pub fn handle_net() -> anyhow::Result<( Connection, UdpSocket )>{
18
18
let addr = env::var("HOST")?.to_socket_addrs()?.nth(0).unwrap();
19
19
20
20
let tcp = TcpStream::connect(addr)?;
21
21
let udp = UdpSocket::bind("0.0.0.0:0")?;
22
22
23
-
let conn = Connection::new(tcp, udp, addr);
24
-
Ok(conn)
23
+
let conn = Connection::new(tcp, udp.try_clone().unwrap(), addr);
24
+
Ok((conn, udp))
25
25
}
+1
-10
client/src/setup.rs
+1
-10
client/src/setup.rs
···
1
1
use bevy::prelude::*;
2
-
use felix_audio::{FelixAudioListener, source::{FelixAudioSource, stream_source::StreamAudioSource}, utils::wav};
2
+
use felix_audio::FelixAudioListener;
3
3
4
4
use crate::debug_camera;
5
5
···
8
8
mut meshes: ResMut<Assets<Mesh>>,
9
9
mut materials: ResMut<Assets<StandardMaterial>>
10
10
){
11
-
let samples = wav::load_wav_file("out.wav");
12
-
let mut samples_index = 0;
13
-
14
11
commands.spawn((
15
12
Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
16
13
MeshMaterial3d(materials.add(Color::WHITE)),
17
14
Transform::from_xyz(5.0, 0.0, 0.0),
18
-
FelixAudioSource::from(StreamAudioSource::new(48_000, move | length | {
19
-
let mono = &samples[samples_index..(samples_index + length)];
20
-
samples_index += length;
21
-
22
-
mono.to_vec()
23
-
}))
24
15
));
25
16
26
17
commands.spawn((
+6
-2
net/src/packet.rs
+6
-2
net/src/packet.rs
···
1
1
use crate::{
2
2
buffer::Buffer,
3
3
packets::{
4
-
link_udp::LinkUDP, notify_connection_info::NotifyConnectionInfo, null::Null, player_join_packet::PlayerJoinPacket, player_leave_packet::PlayerLeavePacket, player_list_packet::PlayerListPacket, update_clients_positions::UpdateClientsPositions, update_server_position::UpdateServerPositions
4
+
link_udp::LinkUDP, notify_connection_info::NotifyConnectionInfo, null::Null, player_join_packet::PlayerJoinPacket, player_leave_packet::PlayerLeavePacket, player_list_packet::PlayerListPacket, player_voice_packet::PlayerVoicePacket, update_clients_positions::UpdateClientsPositions, update_server_position::UpdateServerPositions
5
5
}
6
6
};
7
7
···
16
16
PlayerJoinPacket(PlayerJoinPacket),
17
17
PlayerListPacket(PlayerListPacket),
18
18
PlayerLeavePacket(PlayerLeavePacket),
19
+
20
+
PlayerVoicePacket(PlayerVoicePacket),
19
21
20
22
Null(Null)
21
23
}
22
24
23
25
pub trait Packet{
24
26
fn from_buf(buf: &mut Buffer) -> Self;
25
-
fn to_buf(&self) -> Buffer;
27
+
fn to_buf(self) -> Buffer;
26
28
}
27
29
28
30
pub fn parse(buf: &mut Buffer) -> PacketTypes{
···
38
40
3 => PacketTypes::PlayerJoinPacket(PlayerJoinPacket::from_buf(buf)),
39
41
4 => PacketTypes::PlayerListPacket(PlayerListPacket::from_buf(buf)),
40
42
5 => PacketTypes::PlayerLeavePacket(PlayerLeavePacket::from_buf(buf)),
43
+
44
+
7 => PacketTypes::PlayerVoicePacket(PlayerVoicePacket::from_buf(buf)),
41
45
42
46
_ => PacketTypes::Null(Null::from_buf(buf))
43
47
}
+1
-1
net/src/packets/link_udp.rs
+1
-1
net/src/packets/link_udp.rs
+2
net/src/packets/mod.rs
+2
net/src/packets/mod.rs
+1
-1
net/src/packets/notify_connection_info.rs
+1
-1
net/src/packets/notify_connection_info.rs
+1
-1
net/src/packets/null.rs
+1
-1
net/src/packets/null.rs
+1
-1
net/src/packets/player_join_packet.rs
+1
-1
net/src/packets/player_join_packet.rs
+1
-1
net/src/packets/player_leave_packet.rs
+1
-1
net/src/packets/player_leave_packet.rs
+1
-1
net/src/packets/player_list_packet.rs
+1
-1
net/src/packets/player_list_packet.rs
+30
net/src/packets/player_voice_packet.rs
+30
net/src/packets/player_voice_packet.rs
···
1
+
use crate::{buffer::Buffer, packet::Packet};
2
+
3
+
#[derive(Debug, Clone)]
4
+
pub struct PlayerVoicePacket{
5
+
pub id: String,
6
+
pub packet: Vec<u8>
7
+
}
8
+
9
+
impl Packet for PlayerVoicePacket{
10
+
fn to_buf(self) -> Buffer {
11
+
let mut buf = Buffer::empty();
12
+
buf.set_u16(7);
13
+
14
+
buf.set_str(self.id);
15
+
16
+
buf.set_u32(self.packet.len() as u32);
17
+
buf.set_u8s(&self.packet);
18
+
19
+
buf
20
+
}
21
+
22
+
fn from_buf(buf: &mut Buffer) -> Self {
23
+
let id = buf.get_str();
24
+
25
+
let length = buf.get_u32();
26
+
let packet = buf.get_u8s(length as usize).to_vec();
27
+
28
+
Self { id, packet }
29
+
}
30
+
}
+1
-1
net/src/packets/update_clients_positions.rs
+1
-1
net/src/packets/update_clients_positions.rs
+1
-1
net/src/packets/update_server_position.rs
+1
-1
net/src/packets/update_server_position.rs
+1
server/Cargo.toml
+1
server/Cargo.toml
+6
-1
server/src/net/connection.rs
+6
-1
server/src/net/connection.rs
···
1
-
use std::{io::{Read, Write}, net::{SocketAddr, TcpStream}, sync::mpsc::Sender, thread};
1
+
use std::{io::{Read, Write}, net::{SocketAddr, TcpStream}, thread};
2
2
3
3
use bevy_math::{Quat, Vec3};
4
4
use felix_net::{buffer::Buffer, packet::{self, Packet, PacketTypes}, packets::notify_connection_info::NotifyConnectionInfo};
5
+
use kanal::Sender;
5
6
use nanoid::nanoid;
6
7
7
8
use crate::net::NetServerCommand;
···
72
73
PacketTypes::UpdateServerPositions(packet) => {
73
74
self.position = packet.position;
74
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();
75
80
},
76
81
_ => {}
77
82
}
+10
-4
server/src/net/mod.rs
+10
-4
server/src/net/mod.rs
···
1
-
use std::{collections::HashMap, env, net::{SocketAddr, TcpListener, TcpStream, UdpSocket}, sync::mpsc::channel, thread, time::Duration};
1
+
use std::{collections::HashMap, env, net::{SocketAddr, TcpListener, TcpStream, UdpSocket}, thread, time::Duration};
2
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}};
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
4
5
5
use crate::net::connection::Connection;
6
6
7
7
mod connection;
8
8
9
-
#[derive(Debug)]
10
9
pub enum NetServerCommand{
11
10
CreateConnection(TcpStream),
12
11
LinkUDP(String, SocketAddr),
···
14
13
SendOverUDP(Vec<u8>, SocketAddr),
15
14
RecvOverUDP(SocketAddr, PacketTypes),
16
15
RecvOverTCP(String, PacketTypes),
16
+
BroadcastVoice(PlayerVoicePacket),
17
17
BroadcastPlayerPositions
18
18
}
19
19
···
25
25
let udp_listener = UdpSocket::bind(format!("0.0.0.0:{}", port))?;
26
26
let udp_listener_1 = udp_listener.try_clone()?;
27
27
28
-
let ( sender, recv ) = channel();
28
+
let ( sender, recv ) = kanal::unbounded();
29
29
let sender_1 = sender.clone();
30
30
let sender_2 = sender.clone();
31
31
let sender_3 = sender.clone();
···
130
130
131
131
for (_, conn) in &mut connections{
132
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
+
}
133
139
}
134
140
}
135
141
}