Replicate Sounds (#68)
This commit is contained in:
@@ -1,42 +1,54 @@
|
||||
use crate::config::ServerConfig;
|
||||
use bevy::prelude::*;
|
||||
use lightyear::{
|
||||
connection::client::PeerMetadata,
|
||||
link::LinkConditioner,
|
||||
prelude::{
|
||||
server::{NetcodeConfig, NetcodeServer, ServerUdpIo, Started},
|
||||
server::{ClientOf, NetcodeConfig, NetcodeServer, ServerUdpIo, Started},
|
||||
*,
|
||||
},
|
||||
};
|
||||
use shared::{GameState, global_observer, heads_database::HeadsDatabase, tb_entities::SpawnPoint};
|
||||
use shared::{
|
||||
GameState, global_observer,
|
||||
heads_database::HeadsDatabase,
|
||||
protocol::{
|
||||
ClientEnteredPlaying, channels::UnorderedReliableChannel, messages::AssignClientPlayer,
|
||||
},
|
||||
tb_entities::SpawnPoint,
|
||||
};
|
||||
use std::{
|
||||
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.add_systems(Startup, (start_server, setup_timeout_timer));
|
||||
app.add_systems(
|
||||
OnEnter(GameState::Playing),
|
||||
(start_server, setup_timeout_timer),
|
||||
);
|
||||
app.add_systems(
|
||||
Update,
|
||||
(
|
||||
notify_started.run_if(in_state(GameState::Playing)),
|
||||
run_timeout,
|
||||
),
|
||||
(notify_started, run_timeout).run_if(in_state(GameState::Playing)),
|
||||
);
|
||||
|
||||
global_observer!(app, handle_new_client);
|
||||
global_observer!(app, on_client_connected);
|
||||
global_observer!(app, on_client_playing);
|
||||
global_observer!(app, close_on_disconnect);
|
||||
global_observer!(app, cancel_timeout);
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
struct ClientPlayerId(u8);
|
||||
|
||||
fn handle_new_client(
|
||||
trigger: Trigger<OnAdd, Connected>,
|
||||
trigger: Trigger<OnAdd, Linked>,
|
||||
mut commands: Commands,
|
||||
id: Query<&PeerAddr>,
|
||||
asset_server: Res<AssetServer>,
|
||||
query: Query<&Transform, With<SpawnPoint>>,
|
||||
heads_db: Res<HeadsDatabase>,
|
||||
) -> Result {
|
||||
let id = id.get(trigger.target())?;
|
||||
let Ok(id) = id.get(trigger.target()) else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
info!("Client connected on IP: {}", id.ip());
|
||||
|
||||
@@ -46,11 +58,38 @@ fn handle_new_client(
|
||||
incoming_loss: 0.0,
|
||||
});
|
||||
|
||||
commands
|
||||
.entity(trigger.target())
|
||||
.insert((ReplicationSender::default(), Link::new(Some(conditioner))));
|
||||
commands.entity(trigger.target()).insert((
|
||||
ReplicationSender::default(),
|
||||
Link::new(Some(conditioner)),
|
||||
ClientPlayerId(0),
|
||||
));
|
||||
|
||||
crate::player::spawn(commands, trigger.target(), query, asset_server, heads_db);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_client_connected(
|
||||
trigger: Trigger<OnAdd, ClientOf>,
|
||||
mut assign_player: Query<(&ClientPlayerId, &mut MessageSender<AssignClientPlayer>)>,
|
||||
) -> Result {
|
||||
// `Linked` happens before the `ClientOf` and `MessageSender` components are added, so the server can't
|
||||
// send the client player id until now.
|
||||
let (id, mut sender) = assign_player.get_mut(trigger.target())?;
|
||||
sender.send::<UnorderedReliableChannel>(AssignClientPlayer(id.0));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn on_client_playing(
|
||||
trigger: Trigger<RemoteTrigger<ClientEnteredPlaying>>,
|
||||
commands: Commands,
|
||||
query: Query<&Transform, With<SpawnPoint>>,
|
||||
heads_db: Res<HeadsDatabase>,
|
||||
peers: Res<PeerMetadata>,
|
||||
) -> Result {
|
||||
let Some(&client) = peers.mapping.get(&trigger.from) else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
crate::player::spawn(commands, client, query, heads_db).ok_or("failed to spawn player")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -61,6 +100,7 @@ fn close_on_disconnect(
|
||||
mut writer: EventWriter<AppExit>,
|
||||
) {
|
||||
if config.close_on_client_disconnect {
|
||||
info!("client disconnected, exiting");
|
||||
writer.write(AppExit::Success);
|
||||
}
|
||||
}
|
||||
@@ -103,10 +143,12 @@ fn run_timeout(mut timer: ResMut<TimeoutTimer>, mut writer: EventWriter<AppExit>
|
||||
timer.0 -= time.delta_secs();
|
||||
|
||||
if timer.0 <= 0.0 {
|
||||
info!("client timed out, exiting");
|
||||
writer.write(AppExit::Success);
|
||||
}
|
||||
}
|
||||
|
||||
fn cancel_timeout(_trigger: Trigger<OnAdd, Connected>, mut timer: ResMut<TimeoutTimer>) {
|
||||
info!("client connected, cancelling timeout");
|
||||
timer.0 = f32::INFINITY;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user