69 lines
2.2 KiB
Rust
69 lines
2.2 KiB
Rust
//! Starting the renet network server (host and dedicated modes).
|
|
|
|
use std::{
|
|
net::{Ipv4Addr, SocketAddr, UdpSocket},
|
|
time::SystemTime,
|
|
};
|
|
|
|
use bevy::prelude::*;
|
|
use bevy_replicon::prelude::*;
|
|
use bevy_replicon_renet::{
|
|
RenetChannelsExt, RenetServer,
|
|
netcode::{NetcodeServerTransport, ServerAuthentication, ServerConfig},
|
|
renet::ConnectionConfig,
|
|
};
|
|
|
|
pub const MAX_CLIENTS: usize = 32;
|
|
|
|
/// Opens a UDP server on `port` once all replicon channels are registered.
|
|
pub struct NetworkServerPlugin {
|
|
pub port: u16,
|
|
}
|
|
|
|
#[derive(Resource)]
|
|
struct ServerPort(u16);
|
|
|
|
impl Plugin for NetworkServerPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app.insert_resource(ServerPort(self.port))
|
|
.add_systems(Startup, start_server);
|
|
}
|
|
}
|
|
|
|
fn start_server(mut commands: Commands, channels: Res<RepliconChannels>, port: Res<ServerPort>) {
|
|
match create_server(&channels, port.0) {
|
|
Ok((server, transport)) => {
|
|
info!("listening on UDP port {}", port.0);
|
|
commands.insert_resource(server);
|
|
commands.insert_resource(transport);
|
|
}
|
|
Err(e) => {
|
|
error!("failed to start server on port {}: {e}", port.0);
|
|
commands.write_message(AppExit::error());
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn create_server(
|
|
channels: &RepliconChannels,
|
|
port: u16,
|
|
) -> Result<(RenetServer, NetcodeServerTransport), Box<dyn std::error::Error>> {
|
|
let server = RenetServer::new(ConnectionConfig {
|
|
server_channels_config: channels.server_configs(),
|
|
client_channels_config: channels.client_configs(),
|
|
..Default::default()
|
|
});
|
|
let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
|
|
let socket = UdpSocket::bind((Ipv4Addr::UNSPECIFIED, port))?;
|
|
let server_config = ServerConfig {
|
|
current_time,
|
|
max_clients: MAX_CLIENTS,
|
|
protocol_id: game_core::PROTOCOL_ID,
|
|
authentication: ServerAuthentication::Unsecure,
|
|
// Not used with unsecure authentication, but must be valid.
|
|
public_addresses: vec![SocketAddr::from((Ipv4Addr::LOCALHOST, port))],
|
|
};
|
|
let transport = NetcodeServerTransport::new(server_config, socket)?;
|
|
Ok((server, transport))
|
|
}
|