+78
src/client/debug_camera.rs
+78
src/client/debug_camera.rs
···
1
+
use std::f32::consts::PI;
2
+
3
+
use bevy::{ input::mouse::MouseMotion, prelude::* };
4
+
5
+
use crate::net::client::component::ClientNetworkingManager;
6
+
7
+
#[derive(Component)]
8
+
pub struct DebugCamera{
9
+
pitch: f32,
10
+
yaw: f32
11
+
}
12
+
13
+
impl Default for DebugCamera{
14
+
fn default() -> Self {
15
+
Self {
16
+
pitch: 0.0,
17
+
yaw: -PI / 2.0
18
+
}
19
+
}
20
+
}
21
+
22
+
pub fn fixed_update(
23
+
mut query: Query<(&mut DebugCamera, &mut Transform)>,
24
+
mut networking: Query<&mut ClientNetworkingManager>
25
+
){
26
+
let ( _, transform ) = query.single_mut().unwrap();
27
+
let net_manager = networking.single_mut().unwrap();
28
+
29
+
net_manager.update_server_position(transform.translation.clone(), transform.rotation.clone());
30
+
}
31
+
32
+
pub fn update(
33
+
mut query: Query<(&mut DebugCamera, &mut Transform)>,
34
+
35
+
time: Res<Time>,
36
+
37
+
keys: Res<ButtonInput<KeyCode>>,
38
+
mouse_buttons: Res<ButtonInput<MouseButton>>,
39
+
mut mouse_motion: MessageReader<MouseMotion>,
40
+
){
41
+
let mut delta_time = time.delta_secs();
42
+
if keys.pressed(KeyCode::ShiftLeft){ delta_time *= 2.0; }
43
+
44
+
let ( mut debug, mut transform ) = query.single_mut().unwrap();
45
+
46
+
for ev in mouse_motion.read(){
47
+
if mouse_buttons.pressed(MouseButton::Right){
48
+
debug.pitch -= ev.delta.y * delta_time * 0.1;
49
+
debug.yaw -= ev.delta.x * delta_time * 0.1;
50
+
}
51
+
}
52
+
53
+
transform.rotation = Quat::from_euler(EulerRot::YXZ, debug.yaw, debug.pitch, 0.0);
54
+
55
+
if keys.pressed(KeyCode::KeyW){
56
+
let dir = transform.forward();
57
+
transform.translation += dir * delta_time;
58
+
} else if keys.pressed(KeyCode::KeyS){
59
+
let dir = -transform.forward();
60
+
transform.translation += dir * delta_time;
61
+
}
62
+
63
+
if keys.pressed(KeyCode::KeyA){
64
+
let dir = transform.left();
65
+
transform.translation += dir * delta_time;
66
+
} else if keys.pressed(KeyCode::KeyD){
67
+
let dir = -transform.left();
68
+
transform.translation += dir * delta_time;
69
+
}
70
+
71
+
if keys.pressed(KeyCode::KeyE){
72
+
let dir = transform.up();
73
+
transform.translation += dir * delta_time;
74
+
} else if keys.pressed(KeyCode::KeyQ){
75
+
let dir = -transform.up();
76
+
transform.translation += dir * delta_time;
77
+
}
78
+
}
-65
src/engine/debug_camera.rs
-65
src/engine/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{
7
-
pitch: f32,
8
-
yaw: f32
9
-
}
10
-
11
-
impl Default for DebugCamera{
12
-
fn default() -> Self {
13
-
Self {
14
-
pitch: 0.0,
15
-
yaw: -PI / 2.0
16
-
}
17
-
}
18
-
}
19
-
20
-
pub fn setup(
21
-
mut query: Query<(&mut DebugCamera, &mut Transform)>,
22
-
time: Res<Time>,
23
-
24
-
keys: Res<ButtonInput<KeyCode>>,
25
-
mouse_buttons: Res<ButtonInput<MouseButton>>,
26
-
mut mouse_motion: MessageReader<MouseMotion>,
27
-
){
28
-
let mut delta_time = time.delta_secs();
29
-
if keys.pressed(KeyCode::ShiftLeft){ delta_time *= 2.0; }
30
-
31
-
for ( mut debug, mut transform ) in &mut query{
32
-
for ev in mouse_motion.read(){
33
-
if mouse_buttons.pressed(MouseButton::Right){
34
-
debug.pitch -= ev.delta.y * delta_time * 0.1;
35
-
debug.yaw -= ev.delta.x * delta_time * 0.1;
36
-
}
37
-
}
38
-
39
-
transform.rotation = Quat::from_euler(EulerRot::YXZ, debug.yaw, debug.pitch, 0.0);
40
-
41
-
if keys.pressed(KeyCode::KeyW){
42
-
let dir = transform.forward();
43
-
transform.translation += dir * delta_time;
44
-
} else if keys.pressed(KeyCode::KeyS){
45
-
let dir = -transform.forward();
46
-
transform.translation += dir * delta_time;
47
-
}
48
-
49
-
if keys.pressed(KeyCode::KeyA){
50
-
let dir = transform.left();
51
-
transform.translation += dir * delta_time;
52
-
} else if keys.pressed(KeyCode::KeyD){
53
-
let dir = -transform.left();
54
-
transform.translation += dir * delta_time;
55
-
}
56
-
57
-
if keys.pressed(KeyCode::KeyE){
58
-
let dir = transform.up();
59
-
transform.translation += dir * delta_time;
60
-
} else if keys.pressed(KeyCode::KeyQ){
61
-
let dir = -transform.up();
62
-
transform.translation += dir * delta_time;
63
-
}
64
-
}
65
-
}
src/engine/mod.rs
src/client/mod.rs
src/engine/mod.rs
src/client/mod.rs
+23
-11
src/main.rs
+23
-11
src/main.rs
···
1
-
use bevy::app::{ App, Startup };
2
-
3
1
mod net;
4
2
mod util;
5
3
6
4
#[cfg(feature = "client")]
7
-
mod engine;
5
+
mod client;
8
6
9
7
fn main() {
10
-
let mut app = App::new();
11
-
app.add_systems(Startup, move || net::handle_net().expect("Network Module Failed."));
8
+
9
+
#[cfg(not(feature = "client"))]
10
+
net::handle_net().expect("Network Module Failed.");
12
11
13
12
#[cfg(feature = "client")]
14
13
{
15
-
use bevy::{DefaultPlugins, app::Update};
16
-
app.add_plugins(DefaultPlugins);
14
+
use std::sync::mpsc::channel;
17
15
18
-
app.add_systems(Startup, engine::setup);
19
-
app.add_systems(Update, engine::debug_camera::setup);
20
-
}
16
+
use bevy::{DefaultPlugins, app::{App, FixedUpdate, Startup, Update}, ecs::system::Commands};
21
17
22
-
app.run();
18
+
use crate::net::client::component::ClientNetworkingManager;
19
+
20
+
let (sender, recv) = channel();
21
+
let net_manager = ClientNetworkingManager::from(sender);
22
+
23
+
net::handle_net(recv).expect("Network Module Failed.");
24
+
25
+
App::new()
26
+
.add_plugins(DefaultPlugins)
27
+
.add_systems(Startup, client::setup)
28
+
.add_systems(Startup, move | mut commands: Commands | {
29
+
commands.spawn(net_manager.clone());
30
+
})
31
+
.add_systems(Update, client::debug_camera::update)
32
+
.add_systems(FixedUpdate, client::debug_camera::fixed_update)
33
+
.run();
34
+
}
23
35
}
+27
src/net/client/component.rs
+27
src/net/client/component.rs
···
1
+
use std::sync::mpsc::Sender;
2
+
3
+
use bevy::{ecs::component::Component, math::{Quat, Vec3}};
4
+
5
+
#[derive(Debug, Clone)]
6
+
pub enum ClientNetworkingManagerCommand{
7
+
UpdatePlayerPosition(Vec3, Quat),
8
+
}
9
+
10
+
#[derive(Component, Debug, Clone)]
11
+
pub struct ClientNetworkingManager{
12
+
cmd: Sender<ClientNetworkingManagerCommand>
13
+
}
14
+
15
+
impl From<Sender<ClientNetworkingManagerCommand>> for ClientNetworkingManager{
16
+
fn from(value: Sender<ClientNetworkingManagerCommand>) -> Self {
17
+
Self {
18
+
cmd: value
19
+
}
20
+
}
21
+
}
22
+
23
+
impl ClientNetworkingManager{
24
+
pub fn update_server_position(&self, pos: Vec3, rot: Quat){
25
+
self.cmd.send(ClientNetworkingManagerCommand::UpdatePlayerPosition(pos, rot)).unwrap();
26
+
}
27
+
}
+51
-21
src/net/client/mod.rs
+51
-21
src/net/client/mod.rs
···
1
-
use std::{io::Read, net::{TcpStream, UdpSocket}, thread};
1
+
use std::{net::{TcpStream, UdpSocket}, sync::mpsc::{Receiver, channel}, thread};
2
2
3
-
use crate::net::{packet::{self, Packet, PacketTypes}, packets::link_udp::LinkUDP};
3
+
use bevy::math::{Quat, Vec3};
4
4
5
-
pub fn handle_net_client() -> anyhow::Result<()>{
6
-
let mut tcp = TcpStream::connect("127.0.0.1:2603")?;
7
-
let udp = UdpSocket::bind("0.0.0.0:0")?;
5
+
use crate::{net::{client::component::ClientNetworkingManagerCommand, connection::Connection, packet::PacketTypes, packets::update_server_position::UpdateServerPositions}, util::net::ipv4_address};
8
6
9
-
// TODO: Proper player networking controller
7
+
pub mod component;
10
8
11
-
thread::spawn(move || {
12
-
let mut buf = [0; 1024];
9
+
pub enum NetClientCommand{
10
+
Connected(String),
11
+
Disconnected,
12
+
UpdatePlayerPosition(Vec3, Quat),
13
+
RecvPacket(PacketTypes)
14
+
}
13
15
14
-
while let Ok(length) = tcp.read(&mut buf){
15
-
if length == 0 { break; }
16
+
pub fn handle_net_client(cmd: Receiver<ClientNetworkingManagerCommand>) -> anyhow::Result<()>{
17
+
let tcp = TcpStream::connect("127.0.0.1:2603")?;
18
+
let udp = UdpSocket::bind("0.0.0.0:0")?;
16
19
17
-
let msg = &buf[0..length];
18
-
let packet = packet::parse(msg.into());
20
+
let ( sender_cmd, recv ) = channel();
21
+
let sender_cmd_1 = sender_cmd.clone();
19
22
20
-
match packet{
21
-
PacketTypes::NotifyConnectionInfo(info) => {
22
-
dbg!(&info);
23
+
thread::spawn(move || {
24
+
while let Ok(cmd) = cmd.recv(){
25
+
match cmd{
26
+
ClientNetworkingManagerCommand::UpdatePlayerPosition(pos, rot) =>
27
+
sender_cmd_1.send(NetClientCommand::UpdatePlayerPosition(pos, rot)).unwrap(),
28
+
}
29
+
}
30
+
});
23
31
24
-
let packet = LinkUDP { id: info.id };
25
-
let packet: Vec<_> = packet.to_buf().into();
32
+
thread::spawn(move || {
33
+
let mut conn = Connection::new(tcp, udp,ipv4_address(127, 0, 0, 1, 2603), sender_cmd);
26
34
27
-
udp.send_to(&packet, "127.0.0.1:2603").unwrap();
35
+
while let Ok(cmd) = recv.recv(){
36
+
match cmd{
37
+
NetClientCommand::Connected(id) => {
38
+
println!("[INFO] Connected to server as {}", id);
39
+
conn.id = id;
28
40
},
29
-
_ => {}
41
+
NetClientCommand::Disconnected => {
42
+
println!("[WARN] Disconnected from server.");
43
+
},
44
+
NetClientCommand::UpdatePlayerPosition(pos, rot) => {
45
+
let packet = UpdateServerPositions { position: pos, rotation: rot };
46
+
conn.try_send_unreliable(packet).unwrap();
47
+
},
48
+
NetClientCommand::RecvPacket(packet) => {
49
+
match packet{
50
+
PacketTypes::PlayerJoinPacket(player) => {
51
+
dbg!(player);
52
+
},
53
+
PacketTypes::PlayerListPacket(players) => {
54
+
dbg!(players);
55
+
},
56
+
PacketTypes::PlayerLeavePacket(player) => {
57
+
dbg!(player);
58
+
},
59
+
_ => {}
60
+
}
61
+
}
30
62
}
31
63
}
32
-
33
-
println!("[WARN] Client disconnected from server");
34
64
});
35
65
36
66
Ok(())
+166
src/net/connection.rs
+166
src/net/connection.rs
···
1
+
use std::{fs, io::{Read, Write}, net::{SocketAddr, TcpStream, UdpSocket}, sync::mpsc::Sender, thread};
2
+
3
+
use nanoid::nanoid;
4
+
5
+
#[cfg(feature = "client")]
6
+
use crate::net::{client::NetClientCommand, packets::link_udp::LinkUDP};
7
+
#[cfg(not(feature = "client"))]
8
+
use crate::net::{server::NetServerCommand, packets::notify_connection_info::NotifyConnectionInfo};
9
+
10
+
use crate::net::packet::{self, Packet, PacketTypes};
11
+
12
+
#[derive(Debug)]
13
+
pub struct Connection{
14
+
tcp: TcpStream,
15
+
16
+
#[cfg(not(feature = "client"))]
17
+
udp: Option<SocketAddr>,
18
+
#[cfg(not(feature = "client"))]
19
+
main_thread_sender: Sender<NetServerCommand>,
20
+
21
+
#[cfg(feature = "client")]
22
+
udp: UdpSocket,
23
+
#[cfg(feature = "client")]
24
+
udp_server_address: SocketAddr,
25
+
26
+
pub id: String
27
+
}
28
+
29
+
impl Connection{
30
+
#[cfg(not(feature = "client"))]
31
+
pub fn new( stream: TcpStream, cmd: Sender<NetServerCommand> ) -> Self{
32
+
let mut conn = Self {
33
+
tcp: stream,
34
+
main_thread_sender: cmd.clone(),
35
+
udp: None,
36
+
37
+
id: nanoid!()
38
+
};
39
+
40
+
conn.start_listener_thread(cmd).unwrap();
41
+
42
+
let packet = NotifyConnectionInfo::from(&conn);
43
+
conn.send_reliable(packet).unwrap();
44
+
45
+
conn
46
+
}
47
+
48
+
#[cfg(not(feature = "client"))]
49
+
fn start_listener_thread(&self, cmd: Sender<NetServerCommand>) -> anyhow::Result<()>{
50
+
let mut stream = self.tcp.try_clone()?;
51
+
let id = self.id.clone();
52
+
53
+
thread::spawn(move || {
54
+
let mut buf = [0; 1024];
55
+
while let Ok(length) = stream.read(&mut buf) {
56
+
if length == 0 { break; }
57
+
let msg = &buf[0..length];
58
+
59
+
let packet = packet::parse(msg.into());
60
+
}
61
+
62
+
cmd.send(NetServerCommand::PlayerDisconnect(id)).unwrap();
63
+
});
64
+
65
+
Ok(())
66
+
}
67
+
68
+
#[cfg(feature = "client")]
69
+
pub fn new( tcp: TcpStream, udp: UdpSocket, udp_server_address: SocketAddr, cmd: Sender<NetClientCommand> ) -> Self{
70
+
let mut conn = Self {
71
+
tcp: tcp,
72
+
udp: udp,
73
+
udp_server_address: udp_server_address,
74
+
75
+
id: "".to_owned()
76
+
};
77
+
78
+
conn.start_listener_thread(cmd).unwrap();
79
+
80
+
conn
81
+
}
82
+
83
+
#[cfg(feature = "client")]
84
+
fn start_listener_thread(&self, cmd: Sender<NetClientCommand>) -> anyhow::Result<()>{
85
+
let mut tcp = self.tcp.try_clone()?;
86
+
let udp = self.udp.try_clone()?;
87
+
88
+
let udp_1 = self.udp.try_clone()?;
89
+
let cmd_1 = cmd.clone();
90
+
91
+
let srv_addr = self.udp_server_address.clone();
92
+
93
+
thread::spawn(move || { // UDP RECV THREAD
94
+
let mut buf = [0; 1024];
95
+
96
+
while let Ok((length, addr)) = udp_1.recv_from(&mut buf){
97
+
if addr != srv_addr{ continue; }
98
+
99
+
let msg = &buf[0..length];
100
+
let packet = packet::parse(msg.into());
101
+
102
+
cmd_1.send(NetClientCommand::RecvPacket(packet)).unwrap();
103
+
}
104
+
});
105
+
106
+
thread::spawn(move || { // TCP RECV THREAD
107
+
let mut buf = [0; 1024];
108
+
109
+
while let Ok(length) = tcp.read(&mut buf){
110
+
if length == 0 { break; }
111
+
112
+
let msg = &buf[0..length];
113
+
let packet = packet::parse(msg.into());
114
+
115
+
match packet{
116
+
PacketTypes::NotifyConnectionInfo(info) => {
117
+
cmd.send(NetClientCommand::Connected(info.id.clone())).unwrap();
118
+
119
+
let packet = LinkUDP { id: info.id };
120
+
let packet: Vec<_> = packet.to_buf().into();
121
+
122
+
udp.send_to(&packet, "127.0.0.1:2603").unwrap();
123
+
},
124
+
_ => {
125
+
cmd.send(NetClientCommand::RecvPacket(packet)).unwrap();
126
+
}
127
+
}
128
+
}
129
+
130
+
cmd.send(NetClientCommand::Disconnected).unwrap();
131
+
});
132
+
133
+
Ok(())
134
+
}
135
+
136
+
#[cfg(not(feature = "client"))]
137
+
pub fn connect_udp(&mut self, address: SocketAddr){
138
+
self.udp = Some(address);
139
+
}
140
+
141
+
pub fn send_reliable(&mut self, packet: impl Packet) -> anyhow::Result<()>{
142
+
let buf: Vec<u8> = packet.to_buf().into();
143
+
self.tcp.write(&buf)?;
144
+
145
+
Ok(())
146
+
}
147
+
148
+
pub fn try_send_unreliable(&mut self, packet: impl Packet) -> anyhow::Result<()>{
149
+
let buf: Vec<u8> = packet.to_buf().into();
150
+
151
+
#[cfg(not(feature = "client"))]
152
+
{
153
+
if let Some(addr) = self.udp{
154
+
self.main_thread_sender.send(NetServerCommand::SendOverUDP(buf, addr))?;
155
+
} else{
156
+
println!("[WARN] Cannot send unreliable packet to {}, using TCP instead.", self.id);
157
+
self.tcp.write(&buf)?;
158
+
}
159
+
}
160
+
161
+
#[cfg(feature = "client")]
162
+
self.udp.send_to(&buf, self.udp_server_address)?;
163
+
164
+
Ok(())
165
+
}
166
+
}
+16
-4
src/net/mod.rs
+16
-4
src/net/mod.rs
···
1
1
#[cfg(feature = "client")]
2
-
mod client;
2
+
use std::sync::mpsc::Receiver;
3
+
4
+
#[cfg(feature = "client")]
5
+
use crate::net::client::component::ClientNetworkingManagerCommand;
3
6
7
+
#[cfg(feature = "client")]
8
+
pub mod client;
9
+
10
+
#[cfg(not(feature = "client"))]
4
11
mod server;
5
12
6
13
mod packet;
7
14
mod packets;
8
15
mod buffer;
9
16
10
-
pub fn handle_net() -> anyhow::Result<()>{
11
-
#[cfg(feature = "client")]
12
-
return client::handle_net_client();
17
+
mod connection;
13
18
19
+
#[cfg(feature = "client")]
20
+
pub fn handle_net( cmd: Receiver<ClientNetworkingManagerCommand> ) -> anyhow::Result<()>{
21
+
client::handle_net_client(cmd)
22
+
}
23
+
24
+
#[cfg(not(feature = "client"))]
25
+
pub fn handle_net() -> anyhow::Result<()>{
14
26
server::handle_net_server()
15
27
}
+14
-4
src/net/packet.rs
+14
-4
src/net/packet.rs
···
1
1
use crate::net::{
2
2
buffer::Buffer,
3
3
packets::{
4
-
link_udp::LinkUDP,
5
-
notify_connection_info::NotifyConnectionInfo,
6
-
null::Null, 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, update_server_position::UpdateServerPositions
7
5
}
8
6
};
9
7
10
8
#[derive(Debug)]
11
9
pub enum PacketTypes{
12
-
UpdateServerPositions(UpdateServerPositions),
13
10
NotifyConnectionInfo(NotifyConnectionInfo),
14
11
LinkUDP(LinkUDP),
12
+
13
+
UpdateServerPositions(UpdateServerPositions),
14
+
15
+
PlayerJoinPacket(PlayerJoinPacket),
16
+
PlayerListPacket(PlayerListPacket),
17
+
PlayerLeavePacket(PlayerLeavePacket),
18
+
15
19
Null(Null)
16
20
}
17
21
···
26
30
match id{
27
31
0 => PacketTypes::NotifyConnectionInfo(NotifyConnectionInfo::from_buf(buf)),
28
32
1 => PacketTypes::LinkUDP(LinkUDP::from_buf(buf)),
33
+
29
34
2 => PacketTypes::UpdateServerPositions(UpdateServerPositions::from_buf(buf)),
35
+
36
+
3 => PacketTypes::PlayerJoinPacket(PlayerJoinPacket::from_buf(buf)),
37
+
4 => PacketTypes::PlayerListPacket(PlayerListPacket::from_buf(buf)),
38
+
5 => PacketTypes::PlayerLeavePacket(PlayerLeavePacket::from_buf(buf)),
39
+
30
40
_ => PacketTypes::Null(Null::from_buf(buf))
31
41
}
32
42
}
+5
src/net/packets/mod.rs
+5
src/net/packets/mod.rs
+1
-1
src/net/packets/notify_connection_info.rs
+1
-1
src/net/packets/notify_connection_info.rs
+20
src/net/packets/player_join_packet.rs
+20
src/net/packets/player_join_packet.rs
···
1
+
use crate::net::{buffer::Buffer, packet::Packet};
2
+
3
+
#[derive(Debug, Clone)]
4
+
pub struct PlayerJoinPacket{
5
+
pub id: String
6
+
}
7
+
8
+
impl Packet for PlayerJoinPacket{
9
+
fn to_buf(&self) -> Buffer {
10
+
let mut buf = Buffer::empty();
11
+
buf.set_u16(3);
12
+
buf.set_str(self.id.clone());
13
+
14
+
buf
15
+
}
16
+
17
+
fn from_buf(mut buf: Buffer) -> Self {
18
+
Self { id: buf.get_str() }
19
+
}
20
+
}
+20
src/net/packets/player_leave_packet.rs
+20
src/net/packets/player_leave_packet.rs
···
1
+
use crate::net::{buffer::Buffer, packet::Packet};
2
+
3
+
#[derive(Debug, Clone)]
4
+
pub struct PlayerLeavePacket{
5
+
pub id: String
6
+
}
7
+
8
+
impl Packet for PlayerLeavePacket{
9
+
fn to_buf(&self) -> Buffer {
10
+
let mut buf = Buffer::empty();
11
+
buf.set_u16(5);
12
+
buf.set_str(self.id.clone());
13
+
14
+
buf
15
+
}
16
+
17
+
fn from_buf(mut buf: Buffer) -> Self {
18
+
Self { id: buf.get_str() }
19
+
}
20
+
}
+25
src/net/packets/player_list_packet.rs
+25
src/net/packets/player_list_packet.rs
···
1
+
use crate::net::{buffer::Buffer, packet::Packet};
2
+
3
+
#[derive(Debug, Clone)]
4
+
pub struct PlayerListPacket{
5
+
pub ids: Vec<String>
6
+
}
7
+
8
+
impl Packet for PlayerListPacket{
9
+
fn to_buf(&self) -> Buffer {
10
+
let mut buf = Buffer::empty();
11
+
buf.set_u16(4);
12
+
buf.set_u32(self.ids.len() as u32);
13
+
14
+
for id in &self.ids{ buf.set_str(id.clone()); }
15
+
buf
16
+
}
17
+
18
+
fn from_buf(mut buf: Buffer) -> Self {
19
+
let mut ids = vec![];
20
+
let length = buf.get_u32();
21
+
22
+
for _ in 0..length{ ids.push(buf.get_str()); }
23
+
Self { ids }
24
+
}
25
+
}
-72
src/net/server/connection.rs
-72
src/net/server/connection.rs
···
1
-
use std::{fs, io::{Read, Write}, net::{SocketAddr, TcpStream, UdpSocket}, sync::mpsc::Sender, thread};
2
-
3
-
use nanoid::nanoid;
4
-
5
-
use crate::net::{packet::Packet, packets::notify_connection_info::NotifyConnectionInfo, server::NetServerCommand};
6
-
7
-
#[derive(Debug)]
8
-
pub struct Connection{
9
-
tcp: TcpStream,
10
-
udp: Option<SocketAddr>,
11
-
12
-
pub id: String
13
-
}
14
-
15
-
impl Connection{
16
-
pub fn new( stream: TcpStream, cmd: Sender<NetServerCommand> ) -> Self{
17
-
let mut conn = Self {
18
-
tcp: stream,
19
-
udp: None,
20
-
21
-
id: nanoid!()
22
-
};
23
-
24
-
conn.start_listener_thread(cmd).unwrap();
25
-
26
-
let packet = NotifyConnectionInfo::from(&conn);
27
-
conn.send_reliable(packet).unwrap();
28
-
29
-
conn
30
-
}
31
-
32
-
fn start_listener_thread(&self, cmd: Sender<NetServerCommand>) -> anyhow::Result<()>{
33
-
let mut stream = self.tcp.try_clone()?;
34
-
let id = self.id.clone();
35
-
36
-
thread::spawn(move || {
37
-
let mut buf = [0; 1024];
38
-
while let Ok(length) = stream.read(&mut buf) {
39
-
if length == 0 { break; }
40
-
let msg = &buf[0..length];
41
-
}
42
-
43
-
cmd.send(NetServerCommand::PlayerDisconnect(id)).unwrap();
44
-
});
45
-
46
-
Ok(())
47
-
}
48
-
49
-
pub fn connect_udp(&mut self, address: SocketAddr){
50
-
self.udp = Some(address);
51
-
}
52
-
53
-
pub fn send_reliable(&mut self, packet: impl Packet) -> anyhow::Result<()>{
54
-
let buf: Vec<u8> = packet.to_buf().into();
55
-
self.tcp.write(&buf)?;
56
-
57
-
Ok(())
58
-
}
59
-
60
-
pub fn try_send_unreliable(&mut self, packet: impl Packet) -> anyhow::Result<()>{
61
-
let buf: Vec<u8> = packet.to_buf().into();
62
-
63
-
if let Some(addr) = self.udp{
64
-
UdpSocket::bind("0.0.0.0:0")?.send_to(&buf, addr)?; // TODO: Use shared UDP Socket.
65
-
} else{
66
-
println!("[WARN] Cannot send unreliable packet to {}, using TCP instead.", self.id);
67
-
self.tcp.write(&buf)?;
68
-
}
69
-
70
-
Ok(())
71
-
}
72
-
}
+48
-13
src/net/server/mod.rs
+48
-13
src/net/server/mod.rs
···
1
1
use std::{collections::HashMap, net::{SocketAddr, TcpListener, TcpStream, UdpSocket}, sync::mpsc::channel, thread};
2
2
3
-
use bevy::math::{Quat, Vec3, VectorSpace};
3
+
use bevy::math::{Quat, Vec3};
4
4
5
-
use crate::net::{packet::{self, PacketTypes}, server::{connection::Connection, remote_player::RemotePlayer}};
5
+
use crate::net::{connection::Connection, packet::{self, PacketTypes}, packets::{player_join_packet::PlayerJoinPacket, player_leave_packet::PlayerLeavePacket, player_list_packet::{self, PlayerListPacket}}, server::remote_player::RemotePlayer};
6
6
7
-
pub mod connection;
8
7
pub mod remote_player;
9
8
10
9
pub enum NetServerCommand{
11
10
CreateConnection(TcpStream),
12
11
LinkUDP(String, SocketAddr),
13
-
PlayerDisconnect(String)
12
+
PlayerDisconnect(String),
13
+
SendOverUDP(Vec<u8>, SocketAddr),
14
+
RecvOverUDP(SocketAddr, PacketTypes)
14
15
}
15
16
16
17
pub fn handle_net_server() -> anyhow::Result<()>{
17
18
let tcp_listener = TcpListener::bind("0.0.0.0:2603")?;
19
+
18
20
let udp_listener = UdpSocket::bind("0.0.0.0:2603")?;
21
+
let udp_listener_1 = udp_listener.try_clone()?;
19
22
20
-
let ( sender_1, recv ) = channel();
21
-
let sender_2 = sender_1.clone();
22
-
let sender_3 = sender_1.clone();
23
+
let ( sender, recv ) = channel();
24
+
let sender_1 = sender.clone();
25
+
let sender_2 = sender.clone();
23
26
24
27
thread::spawn(move || {
25
28
loop {
26
29
let ( socket, _ ) = tcp_listener.accept().unwrap();
27
-
sender_1.send(NetServerCommand::CreateConnection(socket)).unwrap();
30
+
sender.send(NetServerCommand::CreateConnection(socket)).unwrap();
28
31
}
29
32
});
30
33
···
39
42
40
43
match packet{
41
44
PacketTypes::LinkUDP(info) => {
42
-
sender_2.send(NetServerCommand::LinkUDP(info.id, address)).unwrap();
45
+
sender_1.send(NetServerCommand::LinkUDP(info.id, address)).unwrap();
46
+
}
47
+
_ => {
48
+
sender_1.send(NetServerCommand::RecvOverUDP(address, packet)).unwrap();
43
49
}
44
-
_ => {}
45
50
}
46
51
}
47
52
});
48
53
49
-
let mut connections = HashMap::new();
50
-
let mut players = HashMap::new();
54
+
let mut connections: HashMap<String, Connection> = HashMap::new();
55
+
let mut connections_by_address: HashMap<SocketAddr, String> = HashMap::new();
56
+
57
+
let mut players: HashMap<String, RemotePlayer> = HashMap::new();
51
58
52
59
while let Ok(cmd) = recv.recv(){
53
60
match cmd{
54
61
NetServerCommand::CreateConnection(socket) => {
55
-
let conn = Connection::new(socket, sender_3.clone());
62
+
let mut conn = Connection::new(socket, sender_2.clone());
56
63
let player = RemotePlayer {
57
64
id: conn.id.clone(),
58
65
position: Vec3::default(),
···
61
68
62
69
println!("[INFO] Connected {}", conn.id);
63
70
71
+
let player_join_packet = PlayerJoinPacket { id: conn.id.clone() };
72
+
73
+
for ( _, player ) in &mut connections{
74
+
player.send_reliable(player_join_packet.clone())?;
75
+
}
76
+
77
+
let player_list_packet = PlayerListPacket {
78
+
ids: players.iter().map(|(id,_)| id.clone()).collect()
79
+
};
80
+
81
+
conn.send_reliable(player_list_packet).unwrap();
82
+
64
83
connections.insert(conn.id.clone(), conn);
65
84
players.insert(player.id.clone(), player);
66
85
}
67
86
NetServerCommand::LinkUDP(id, addr) => {
68
87
if let Some(conn) = connections.get_mut(&id){
88
+
connections_by_address.insert(addr.clone(), id);
69
89
conn.connect_udp(addr);
70
90
}
71
91
},
···
73
93
players.remove(&id);
74
94
connections.remove(&id);
75
95
96
+
let player_leave_packet = PlayerLeavePacket { id: id.clone() };
97
+
98
+
for ( _, player ) in &mut connections{
99
+
player.send_reliable(player_leave_packet.clone())?;
100
+
}
101
+
76
102
println!("[INFO] Disconnected {}", id);
103
+
},
104
+
NetServerCommand::SendOverUDP(buf, addr) => {
105
+
udp_listener_1.send_to(&buf, addr)?;
106
+
},
107
+
NetServerCommand::RecvOverUDP(addr, packet) => {
108
+
let conn_id = &connections_by_address[&addr];
109
+
let conn = &connections[conn_id];
110
+
111
+
77
112
}
78
113
}
79
114
}