Skip to content

Commit

Permalink
split renet2 crate into renet2 and renet2_netcode; move steam bevy in…
Browse files Browse the repository at this point in the history
…tegration to bevy_renet2; ClientId is now a type alias for u64
  • Loading branch information
UkoeHB committed Dec 22, 2024
1 parent 3c0ebc4 commit 15ba550
Show file tree
Hide file tree
Showing 71 changed files with 477 additions and 546 deletions.
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
[workspace]
members = [
"examples/echo_client_native",
#"examples/echo_client_wt", # requires wasm32-unknown-unknown target
#"examples/echo_client_wasm", # requires wasm32-unknown-unknown target
"examples/echo_server_cross",
"demo_chat",
"demo_bevy",
"bevy_renet2",
"bevy_replicon_renet2",
"renet2",
"renet2_netcode",
"renet2_visualizer",
"renet2_steam",
"renetcode2",
]
exclude = [
"examples/echo_client_wt",
"examples/echo_client_wasm",
]
resolver = "2"
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ Provides the following features:
Renet2 extends the original [netcode](https://github.com/networkprotocol/netcode) protocol with:

- Optional packet encryption. This supports data transports that do their own encryption.
- Servers with multiple concurrent data sources (e.g. UDP sockets and WebTransport).
- Optional transport reliability. This supports data transports that are automatically reliable.
- Servers with multiple concurrent data transports (e.g. UDP sockets and WebTransport).

See `renetcode2/NETCODE_EXTENSIONS.md`.

### Features

- Includes built-in data transports: UDP, memory channels, WebTransport, WebSockets.
- See `src/examples` for a fully cross-platform demo.


## Building docs
Expand All @@ -44,10 +46,10 @@ Build workspace docs (no WASM):
cargo doc --open --no-deps --all-features
```

Build WASM docs (`renet2` workspace crate only):
Build WASM docs (`renet2_netcode` workspace crate only):
```
cd renet2 &&\
cargo doc --open --no-deps --no-default-features --features=wt_client_transport,ws_client_transport,transport --target wasm32-unknown-unknown
cd renet2_netcode &&\
cargo doc --open --no-deps --no-default-features --features=wt_client_transport,ws_client_transport --target wasm32-unknown-unknown
```


Expand Down Expand Up @@ -133,7 +135,7 @@ loop {
// Send a text message for all clients
server.broadcast_message(DefaultChannel::ReliableOrdered, "server message");

let client_id = ClientId::from_raw(0);
let client_id = 0;
// Send a text message for all clients except for Client 0
server.broadcast_message_except(client_id, DefaultChannel::ReliableOrdered, "server message");

Expand Down
27 changes: 17 additions & 10 deletions bevy_renet2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,39 @@ readme = "README.md"
repository = "https://github.com/UkoeHB/renet2"

[package.metadata.docs.rs]
features = ["default", "serde", "native_transport", "memory_transport", "wt_server_transport"]
features = ["default", "serde"]
rustdoc-args = ["-Zunstable-options", "--cfg", "docsrs"]

[features]
default = ["transport"]
serde = ["renet2/serde"]
transport = ["renet2/transport"]
native_transport = ["transport", "renet2/native_transport"]
memory_transport = ["transport", "renet2/memory_transport"]
wt_server_transport = ["transport", "renet2/wt_server_transport"]
wt_client_transport = ["transport", "renet2/wt_client_transport"]
default = ["netcode"]
serde = ["renet2_netcode/serde"]
steam = ["dep:renet2_steam", "dep:steamworks"]
netcode = ["dep:renet2_netcode"]
native_transport = ["netcode", "renet2_netcode/native_transport"]
memory_transport = ["netcode", "renet2_netcode/memory_transport"]
wt_server_transport = ["netcode", "renet2_netcode/wt_server_transport"]
wt_client_transport = ["netcode", "renet2_netcode/wt_client_transport"]
ws_server_transport = ["netcode", "renet2_netcode/ws_server_transport"]
ws_client_transport = ["netcode", "renet2_netcode/ws_client_transport"]

[[example]]
name = "simple"
required-features = ["serde", "transport"]
required-features = ["serde", "netcode"]

[dependencies]
bevy_app = {version = "0.15", default-features = false}
bevy_ecs = {version = "0.15", default-features = false}
bevy_time = {version = "0.15", default-features = false}
renet2 = {path = "../renet2", version = "0.0.7", default-features = false, features = ["bevy"]}
renet2_netcode = {path = "../renet2_netcode", version = "0.0.7", optional = true, default-features = false, features = ["bevy"]}
renet2_steam = {path = "../renet2_steam", version = "0.0.7", optional = true, default-features = false, features = ["bevy"]}
steamworks = {version = "0.11", optional = true}

[dev-dependencies]
bevy = {version = "0.15", default-features = false, features = ["bevy_core_pipeline", "bevy_render", "bevy_asset", "bevy_pbr", "x11", "tonemapping_luts", "ktx2", "zstd"]}
bincode = "1.3"
env_logger = "0.11"
renet2 = {path = "../renet2", version = "0.0.7", default-features = false, features = ["bevy", "memory_transport"]}
renet2 = {path = "../renet2", version = "0.0.7", default-features = false, features = ["bevy"] }
renet2_netcode = {path = "../renet2_netcode", version = "0.0.7", default-features = false, features = ["bevy", "memory_transport"]}
serde = {version = "1.0", features = ["derive"]}
tracing-subscriber = { version = "0.3", features = [ "env-filter", "std", "tracing-log" ] }
17 changes: 6 additions & 11 deletions bevy_renet2/examples/simple.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
use bevy::{prelude::*, render::mesh::PlaneMeshBuilder};
use bevy_renet2::{
client_connected,
renet2::{
transport::{ClientAuthentication, ServerAuthentication, ServerSetupConfig},
ConnectionConfig, DefaultChannel, RenetClient, RenetServer, ServerEvent,
},
transport::{NetcodeClientPlugin, NetcodeServerPlugin},
RenetClientPlugin, RenetServerPlugin,
use bevy_renet2::netcode::{
ClientAuthentication, NativeSocket, NetcodeClientPlugin, NetcodeClientTransport, NetcodeServerPlugin, NetcodeServerTransport,
NetcodeTransportError, ServerAuthentication, ServerSetupConfig,
};
use renet2::{
transport::{NativeSocket, NetcodeClientTransport, NetcodeServerTransport, NetcodeTransportError},
ClientId,
use bevy_renet2::prelude::{
client_connected, ClientId, ConnectionConfig, DefaultChannel, RenetClient, RenetClientPlugin, RenetServer, RenetServerPlugin,
ServerEvent,
};

use std::time::SystemTime;
Expand Down
120 changes: 9 additions & 111 deletions bevy_renet2/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,117 +1,15 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
pub use renet2;

use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use bevy_time::prelude::*;
#[cfg(feature = "netcode")]
pub mod netcode;

use renet2::{RenetClient, RenetServer, ServerEvent};
#[cfg(feature = "steam")]
pub mod steam;

#[cfg(feature = "transport")]
pub mod transport;
mod renet2;
mod run_conditions;

/// This system set is where all transports receive messages
///
/// If you want to ensure data has arrived in the [`RenetClient`] or [`RenetServer`], then schedule your
/// system after this set.
///
/// This system set runs in PreUpdate.
#[derive(Debug, SystemSet, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RenetReceive;

/// This system set is where all transports send messages
///
/// If you want to ensure your packets have been registered by the [`RenetClient`] or [`RenetServer`], then
/// schedule your system before this set.
///
/// This system set runs in PostUpdate.
#[derive(Debug, SystemSet, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RenetSend;

pub struct RenetServerPlugin;

pub struct RenetClientPlugin;

impl Plugin for RenetServerPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<Events<ServerEvent>>();
app.add_systems(PreUpdate, Self::update_system.run_if(resource_exists::<RenetServer>));
app.add_systems(
PreUpdate,
Self::emit_server_events_system
.in_set(RenetReceive)
.run_if(resource_exists::<RenetServer>)
.after(Self::update_system),
);
}
}

impl RenetServerPlugin {
pub fn update_system(mut server: ResMut<RenetServer>, time: Res<Time>) {
server.update(time.delta());
}

pub fn emit_server_events_system(mut server: ResMut<RenetServer>, mut server_events: EventWriter<ServerEvent>) {
while let Some(event) = server.get_event() {
server_events.send(event);
}
}
}

impl Plugin for RenetClientPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PreUpdate, Self::update_system.run_if(client_should_update()));
}
}

impl RenetClientPlugin {
pub fn update_system(mut client: ResMut<RenetClient>, time: Res<Time>) {
client.update(time.delta());
}
}

pub fn client_connected(client: Option<Res<RenetClient>>) -> bool {
match client {
Some(client) => client.is_connected(),
None => false,
}
}

pub fn client_disconnected(client: Option<Res<RenetClient>>) -> bool {
match client {
Some(client) => client.is_disconnected(),
None => true,
}
}

pub fn client_connecting(client: Option<Res<RenetClient>>) -> bool {
match client {
Some(client) => client.is_connecting(),
None => false,
}
}

pub fn client_just_connected(mut last_connected: Local<bool>, client: Option<Res<RenetClient>>) -> bool {
let connected = client.map(|client| client.is_connected()).unwrap_or(false);

let just_connected = !*last_connected && connected;
*last_connected = connected;
just_connected
}

pub fn client_just_disconnected(mut last_connected: Local<bool>, client: Option<Res<RenetClient>>) -> bool {
let disconnected = client.map(|client| client.is_disconnected()).unwrap_or(true);

let just_disconnected = *last_connected && disconnected;
*last_connected = !disconnected;
just_disconnected
}

pub fn client_should_update() -> impl Condition<()> {
// (just_disconnected || !disconnected) && exists<RenetClient>
IntoSystem::into_system(
client_just_disconnected
.or(not(client_disconnected))
.and(resource_exists::<RenetClient>),
)
pub mod prelude {
pub use crate::renet2::*;
pub use crate::run_conditions::*;
}
9 changes: 4 additions & 5 deletions bevy_renet2/src/transport.rs → bevy_renet2/src/netcode.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use renet2::{
transport::{NetcodeClientTransport, NetcodeServerTransport, NetcodeTransportError},
RenetClient, RenetServer,
};
pub use renet2_netcode::*;

use renet2::{RenetClient, RenetServer};

use bevy_app::{prelude::*, AppExit};
use bevy_ecs::prelude::*;
use bevy_time::prelude::*;

use crate::{client_should_update, RenetClientPlugin, RenetReceive, RenetSend, RenetServerPlugin};
use crate::prelude::{client_should_update, RenetClientPlugin, RenetReceive, RenetSend, RenetServerPlugin};

pub struct NetcodeServerPlugin;

Expand Down
67 changes: 67 additions & 0 deletions bevy_renet2/src/renet2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
pub use renet2::*;

use bevy_app::prelude::*;
use bevy_ecs::prelude::*;
use bevy_time::prelude::*;

use crate::prelude::client_should_update;

/// This system set is where all transports receive messages
///
/// If you want to ensure data has arrived in the [`RenetClient`] or [`RenetServer`], then schedule your
/// system after this set.
///
/// This system set runs in PreUpdate.
#[derive(Debug, SystemSet, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RenetReceive;

/// This system set is where all transports send messages
///
/// If you want to ensure your packets have been registered by the [`RenetClient`] or [`RenetServer`], then
/// schedule your system before this set.
///
/// This system set runs in PostUpdate.
#[derive(Debug, SystemSet, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RenetSend;

pub struct RenetServerPlugin;

pub struct RenetClientPlugin;

impl Plugin for RenetServerPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<Events<ServerEvent>>();
app.add_systems(PreUpdate, Self::update_system.run_if(resource_exists::<RenetServer>));
app.add_systems(
PreUpdate,
Self::emit_server_events_system
.in_set(RenetReceive)
.run_if(resource_exists::<RenetServer>)
.after(Self::update_system),
);
}
}

impl RenetServerPlugin {
pub fn update_system(mut server: ResMut<RenetServer>, time: Res<Time>) {
server.update(time.delta());
}

pub fn emit_server_events_system(mut server: ResMut<RenetServer>, mut server_events: EventWriter<ServerEvent>) {
while let Some(event) = server.get_event() {
server_events.send(event);
}
}
}

impl Plugin for RenetClientPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PreUpdate, Self::update_system.run_if(client_should_update()));
}
}

impl RenetClientPlugin {
pub fn update_system(mut client: ResMut<RenetClient>, time: Res<Time>) {
client.update(time.delta());
}
}
49 changes: 49 additions & 0 deletions bevy_renet2/src/run_conditions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use bevy_ecs::prelude::*;

use renet2::RenetClient;

pub fn client_connected(client: Option<Res<RenetClient>>) -> bool {
match client {
Some(client) => client.is_connected(),
None => false,
}
}

pub fn client_disconnected(client: Option<Res<RenetClient>>) -> bool {
match client {
Some(client) => client.is_disconnected(),
None => true,
}
}

pub fn client_connecting(client: Option<Res<RenetClient>>) -> bool {
match client {
Some(client) => client.is_connecting(),
None => false,
}
}

pub fn client_just_connected(mut last_connected: Local<bool>, client: Option<Res<RenetClient>>) -> bool {
let connected = client.map(|client| client.is_connected()).unwrap_or(false);

let just_connected = !*last_connected && connected;
*last_connected = connected;
just_connected
}

pub fn client_just_disconnected(mut last_connected: Local<bool>, client: Option<Res<RenetClient>>) -> bool {
let disconnected = client.map(|client| client.is_disconnected()).unwrap_or(true);

let just_disconnected = *last_connected && disconnected;
*last_connected = !disconnected;
just_disconnected
}

pub fn client_should_update() -> impl Condition<()> {
// (just_disconnected || !disconnected) && exists<RenetClient>
IntoSystem::into_system(
client_just_disconnected
.or(not(client_disconnected))
.and(resource_exists::<RenetClient>),
)
}
Loading

0 comments on commit 15ba550

Please sign in to comment.