Skip to content

Commit

Permalink
player physics networking and syncing and player connection and disco…
Browse files Browse the repository at this point in the history
…nnection working
  • Loading branch information
MalekiRe committed Sep 27, 2024
1 parent fedc390 commit a79e3f4
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 42 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ bevy_mod_openxr = { git = "https://github.com/awtterpip/bevy_oxr" }
bevy_spatial_egui = { path = "../bevy_spatial_egui" }
bevy_egui = "0.29.0"
bevy-suis = { git = "https://github.com/Schmarni-Dev/bevy-suis", branch = "further_work" }

bevy_vrm = "0.0.12"
[profile.release]
lto = "thin"
opt-level = "z"

[profile.dev]
opt-level = 3
16 changes: 12 additions & 4 deletions src/file_sharing.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::networking::{Connection, ConnectionTrait, ReliableMessage};
use bevy::prelude::*;
use bevy::reflect::List;
use bevy_matchbox::prelude::MultipleChannels;
use bevy_matchbox::MatchboxSocket;
use futures_channel::mpsc::{channel, Receiver, SendError, Sender};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use bevy_matchbox::MatchboxSocket;
use bevy_matchbox::prelude::MultipleChannels;
use uuid::Uuid;

#[derive(Clone, Debug, Serialize, Deserialize, Event)]
Expand Down Expand Up @@ -41,8 +41,16 @@ impl Plugin for FileSharingPlugin {
let (tx, rx) = channel(100);
app.insert_resource(P2pFileRx(rx));
app.insert_resource(P2pFileSender(tx));
app.add_systems(Update, handle_file_part.run_if(resource_exists::<MatchboxSocket<MultipleChannels>>));
app.add_systems(Update, send_parts_of_file.run_if(resource_exists::<MatchboxSocket<MultipleChannels>>));
app.add_systems(
Update,
handle_file_part
.run_if(resource_exists::<MatchboxSocket<MultipleChannels>>),
);
app.add_systems(
Update,
send_parts_of_file
.run_if(resource_exists::<MatchboxSocket<MultipleChannels>>),
);
}
}

Expand Down
112 changes: 85 additions & 27 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::file_sharing::FileSharingPlugin;
use crate::networking::{ConnectToRoom, NetworkingPlugin};
use avian3d::prelude::{Collider, CollisionLayers, RigidBody};
use crate::networking::{ConnectToRoom, LocalPlayer, NetworkingPlugin, SpawnPlayer};
use crate::player_networking::PlayerNetworking;
use avian3d::prelude::{Collider, CollisionLayers, GravityScale, LockedAxes, RigidBody};
use avian3d::PhysicsPlugins;
use bevy::app::App;
use bevy::asset::{AssetMetaCheck, AssetServer, Assets, Handle};
Expand All @@ -17,36 +18,46 @@ use bevy_suis::debug::SuisDebugGizmosPlugin;
use bevy_suis::window_pointers::SuisWindowPointerPlugin;
use bevy_suis::SuisCorePlugin;
use bevy_vr_controller::animation::defaults::default_character_animations;
use bevy_vr_controller::player::PlayerSettings;
use bevy_vr_controller::movement::PlayerInputState;
use bevy_vr_controller::player::{
PlayerAvatar, PlayerBody, PlayerHeight, PlayerJumpHeight, PlayerSettings,
PlayerSpawn, PlayerSpeed, SpawnedPlayer, VoidTeleport,
};
use bevy_vr_controller::velocity::AverageVelocity;
use bevy_vr_controller::VrControllerPlugin;
use bevy_vrm::VrmBundle;
use uuid::Uuid;
use crate::physics_sync::PhysicsSyncNetworkingPlugin;

mod file_sharing;
pub mod networking;
mod player_networking;
mod physics_sync;

pub fn main() {
App::new()
.add_plugins((
EmbeddedAssetPlugin::default(),
bevy_web_file_drop::WebFileDropPlugin,
DefaultPlugins.set(AssetPlugin {
meta_check: AssetMetaCheck::Never,
..AssetPlugin::default()
}),
PhysicsPlugins::default(),
VrControllerPlugin,
))
.add_plugins((
SuisCorePlugin,
SuisWindowPointerPlugin,
SuisDebugGizmosPlugin,
))
.add_plugins(bevy_spatial_egui::SpatialEguiPlugin)
.add_plugins(EguiPlugin)
.add_plugins((NetworkingPlugin, FileSharingPlugin))
.add_systems(Startup, setup_main_window)
.add_systems(Startup, (setup_scene, setup_player))
.add_systems(Update, draw_ui)
.run();
.add_plugins((
EmbeddedAssetPlugin::default(),
bevy_web_file_drop::WebFileDropPlugin,
DefaultPlugins.set(AssetPlugin {
meta_check: AssetMetaCheck::Never,
..AssetPlugin::default()
}),
PhysicsPlugins::default(),
VrControllerPlugin,
))
.add_plugins((
SuisCorePlugin,
SuisWindowPointerPlugin,
//SuisDebugGizmosPlugin,
))
.add_plugins(bevy_spatial_egui::SpatialEguiPlugin)
.add_plugins(EguiPlugin)
.add_plugins((NetworkingPlugin, FileSharingPlugin, PlayerNetworking, PhysicsSyncNetworkingPlugin))
.add_systems(Startup, setup_main_window)
.add_systems(Startup, (setup_scene, setup_player))
.add_systems(Update, draw_ui)
.run();
}

fn draw_ui(mut query: Query<&mut EguiContext, With<MainWindow>>) {
Expand Down Expand Up @@ -81,14 +92,61 @@ const GROUND_SIZE: f32 = 30.0;
const GROUND_THICK: f32 = 0.2;

fn setup_player(asset_server: Res<AssetServer>, mut commands: Commands) {
PlayerSettings {
let awa = PlayerSettings {
animations: Some(default_character_animations(&asset_server)),
vrm: Some(asset_server.load("embedded://models/robot.vrm")),
void_level: Some(-20.0),
spawn: Vec3::new(0.0, 3.0, 0.0),
..default()
}
.spawn(&mut commands);
.spawn(&mut commands);
commands.entity(awa.body).insert(LocalPlayer(Uuid::new_v4()));
}

pub fn spawn_avatar(this: PlayerSettings, commands: &mut Commands) -> Entity {
let mut body = commands.spawn((
Collider::capsule(this.width / 2.0, this.height - this.width),
LockedAxes::ROTATION_LOCKED,
PlayerBody,
PlayerSpawn(this.spawn),
RigidBody::Dynamic,
SpatialBundle {
global_transform: GlobalTransform::from_translation(this.spawn),
..default()
},
GravityScale(0.0)
));

if let Some(value) = this.void_level {
body.insert(VoidTeleport(value));
}

let body = body.id();

let mut avatar = commands.spawn((
PlayerAvatar,
AverageVelocity {
target: Some(body),
..default()
},
VrmBundle {
scene_bundle: SceneBundle {
transform: Transform::from_xyz(0.0, -this.height / 2.0, 0.0),
..default()
},
vrm: this.vrm.clone().unwrap_or_default(),
..default()
},
));

if let Some(value) = &this.animations {
avatar.insert(value.clone());
}

let avatar = avatar.id();

commands.entity(body).push_children(&[avatar]);
body
}

fn setup_scene(
Expand Down
106 changes: 96 additions & 10 deletions src/networking.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::file_sharing::FileParts;
use avian3d::prelude::{AngularVelocity, LinearVelocity, Position};
use bevy::app::App;
use bevy::ecs::system::{EntityCommand, SystemParam};
use bevy::ecs::world::Command;
use bevy::prelude::*;
use bevy_derive::{Deref, DerefMut};
use bevy_matchbox::prelude::{MultipleChannels, PeerId, WebRtcSocketBuilder};
use bevy_matchbox::prelude::{
MultipleChannels, PeerId, PeerState, WebRtcSocketBuilder,
};
use bevy_matchbox::MatchboxSocket;
use futures_channel::mpsc::SendError;
use serde::{Deserialize, Serialize};
Expand All @@ -25,6 +28,7 @@ pub enum UnreliableMessage {
#[derive(Clone, Debug, Serialize, Deserialize, Event)]
pub struct SpawnPlayer {
pub uuid: Uuid,
pub peer_id: Option<PeerId>,
}

#[derive(Clone, Debug, Serialize, Deserialize, Event)]
Expand Down Expand Up @@ -55,9 +59,9 @@ pub struct PlayerPositionUpdate {
pub struct LocalPlayer(pub Uuid);

#[derive(
Reflect, Clone, Debug, Serialize, Deserialize, Deref, DerefMut, PartialEq, Component,
Clone, Debug, Serialize, Deserialize, PartialEq, Component,
)]
pub struct RemotePlayer(pub Uuid);
pub struct RemotePlayer(pub Uuid, pub PeerId);

pub trait ConnectToRoom {
fn connect_to_room(&mut self, room: impl AsRef<str>);
Expand All @@ -80,15 +84,77 @@ impl ConnectToRoom for Commands<'_, '_> {
pub struct NetworkingPlugin;
impl Plugin for NetworkingPlugin {
fn build(&self, app: &mut App) {
app.add_event::<SpawnPlayer>();
app.add_event::<PlayerConnected>();
app.add_event::<PlayerDisconnected>();
app.add_event::<UpdatePhysicsPosition>();

app.add_systems(
FixedUpdate,
update_peers.run_if(resource_exists::<MatchboxSocket<MultipleChannels>>),
);
app.add_systems(
Update,
(handle_messages_reliable, handle_messages_unreliable),
);
}
}

fn handle_messages_reliable(
mut connection: Connection,
mut spawn_players: EventWriter<SpawnPlayer>,
mut file_parts: ResMut<FileParts>,
) {
for (message, peer_id) in connection.recv() {
let message: ReliableMessage = message;
match message {
ReliableMessage::SpawnPlayer(mut spawn_player) => {
spawn_player.peer_id.replace(peer_id);
spawn_players.send(spawn_player);
}
ReliableMessage::FilePart(file_part) => {
file_parts.0.push(file_part);
}
}
}
}

fn handle_messages_unreliable(
mut connection: Connection,
mut update_physics_positions: EventWriter<UpdatePhysicsPosition>,
) {
for (message, _peer_id) in connection.recv() {
let message: UnreliableMessage = message;
match message {
UnreliableMessage::UpdatePhysicsPosition(update_physics_position) => {
update_physics_positions.send(update_physics_position);
}
UnreliableMessage::PlayerPositionUpdate(_) => todo!(),
}
}
}

fn update_peers(mut socket: ResMut<MatchboxSocket<MultipleChannels>>) {
socket.update_peers();
#[derive(Event)]
pub struct PlayerDisconnected(pub PeerId);

#[derive(Event)]
pub struct PlayerConnected(pub PeerId);

fn update_peers(
mut socket: ResMut<MatchboxSocket<MultipleChannels>>,
mut player_connected: EventWriter<PlayerConnected>,
mut player_disconnected: EventWriter<PlayerDisconnected>,
) {
for (peer, state) in socket.update_peers() {
match state {
PeerState::Connected => {
player_connected.send(PlayerConnected(peer));
}
PeerState::Disconnected => {
player_disconnected.send(PlayerDisconnected(peer));
}
}
}
}

#[derive(SystemParam)]
Expand All @@ -98,7 +164,7 @@ pub struct Connection<'w> {

pub trait ConnectionTrait<MessageType> {
fn peers(&self) -> Vec<PeerId>;
fn update_peers(&mut self);
fn update_peers(&mut self) -> Vec<(PeerId, PeerState)>;
fn send(
&mut self,
peer: bevy_matchbox::prelude::PeerId,
Expand All @@ -125,15 +191,17 @@ pub trait ConnectionTrait<MessageType> {
Some(vec) => Err(vec),
}
}

fn recv(&mut self) -> Vec<(MessageType, PeerId)>;
}

impl ConnectionTrait<UnreliableMessage> for Connection<'_> {
fn peers(&self) -> Vec<PeerId> {
self.socket.connected_peers().collect::<Vec<_>>()
}

fn update_peers(&mut self) {
self.socket.update_peers();
fn update_peers(&mut self) -> Vec<(PeerId, PeerState)> {
self.socket.update_peers()
}

fn send(
Expand All @@ -146,15 +214,24 @@ impl ConnectionTrait<UnreliableMessage> for Connection<'_> {
.channel_mut(1)
.try_send(Box::from(encoded), peer)
}

fn recv(&mut self) -> Vec<(UnreliableMessage, PeerId)> {
self.socket
.channel_mut(1)
.receive()
.into_iter()
.map(|(peer_id, packet)| (bincode::deserialize(&packet).unwrap(), peer_id))
.collect()
}
}

impl ConnectionTrait<ReliableMessage> for Connection<'_> {
fn peers(&self) -> Vec<PeerId> {
self.socket.connected_peers().collect::<Vec<_>>()
}

fn update_peers(&mut self) {
self.socket.update_peers();
fn update_peers(&mut self) -> Vec<(PeerId, PeerState)> {
self.socket.update_peers()
}

fn send(
Expand All @@ -167,4 +244,13 @@ impl ConnectionTrait<ReliableMessage> for Connection<'_> {
.channel_mut(0)
.try_send(Box::from(encoded), peer)
}

fn recv(&mut self) -> Vec<(ReliableMessage, PeerId)> {
self.socket
.channel_mut(0)
.receive()
.into_iter()
.map(|(peer_id, packet)| (bincode::deserialize(&packet).unwrap(), peer_id))
.collect()
}
}
Loading

0 comments on commit a79e3f4

Please sign in to comment.