Skip to content

Commit

Permalink
bevy steam
Browse files Browse the repository at this point in the history
  • Loading branch information
lucaspoffo committed Jul 20, 2023
1 parent dcc64ff commit 68b8f7f
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 24 deletions.
2 changes: 2 additions & 0 deletions bevy_renet/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ version = "0.0.9"
[features]
default = ["transport"]
transport = ["renet/transport"]
steam = ["renet_steam"]

[dependencies]
bevy = {version = "0.11", default-features = false}
renet = {path = "../renet", version = "0.0.13", features = ["bevy"]}
renet_steam = { path = "../renet_steam", version = "0.0.1", features = [ "bevy" ], optional = true }

[dev-dependencies]
bevy = {version = "0.11", default-features = false, features = ["bevy_core_pipeline", "bevy_render", "bevy_asset", "bevy_pbr", "x11", "tonemapping_luts", "ktx2", "zstd"]}
Expand Down
1 change: 0 additions & 1 deletion bevy_renet/examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ enum ServerMessages {

fn new_renet_client() -> (RenetClient, NetcodeClientTransport) {
let client = RenetClient::new(ConnectionConfig::default());

let server_addr = "127.0.0.1:5000".parse().unwrap();
let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
let current_time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
Expand Down
4 changes: 4 additions & 0 deletions bevy_renet/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ use renet::{RenetClient, RenetServer, ServerEvent};

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

#[cfg(feature = "steam")]
pub mod steam;

pub struct RenetServerPlugin;

pub struct RenetClientPlugin;
Expand Down
138 changes: 138 additions & 0 deletions bevy_renet/src/steam.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
use bevy::{app::AppExit, prelude::*};
use renet::{RenetClient, RenetServer};
use renet_steam::steamworks::SteamError;

use crate::{RenetClientPlugin, RenetServerPlugin};

pub use renet_steam::{SteamClientTransport, SteamServerTransport};

pub struct SteamServerPlugin;

pub struct SteamClientPlugin;

#[derive(Debug, Event)]
pub struct SteamNetError(pub SteamError);

impl Plugin for SteamServerPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
PreUpdate,
Self::update_system
.run_if(resource_exists::<SteamServerTransport>())
.run_if(resource_exists::<RenetServer>())
.after(RenetServerPlugin::update_system),
);

app.add_systems(
PostUpdate,
(Self::send_packets, Self::disconnect_on_exit)
.run_if(resource_exists::<SteamServerTransport>())
.run_if(resource_exists::<RenetServer>()),
);
}
}

impl SteamServerPlugin {
pub fn update_system(mut transport: ResMut<SteamServerTransport>, mut server: ResMut<RenetServer>) {
transport.update(&mut server);
}

pub fn send_packets(mut transport: ResMut<SteamServerTransport>, mut server: ResMut<RenetServer>) {
transport.send_packets(&mut server);
}

pub fn disconnect_on_exit(exit: EventReader<AppExit>, mut transport: ResMut<SteamServerTransport>, mut server: ResMut<RenetServer>) {
if !exit.is_empty() {
transport.disconnect_all(&mut server, false);
}
}
}

impl Plugin for SteamClientPlugin {
fn build(&self, app: &mut App) {
app.add_event::<SteamNetError>();

app.add_systems(
PreUpdate,
Self::update_system
.run_if(resource_exists::<SteamClientTransport>())
.run_if(resource_exists::<RenetClient>())
.after(RenetClientPlugin::update_system),
);
app.add_systems(
PostUpdate,
(Self::send_packets, Self::disconnect_on_exit)
.run_if(resource_exists::<SteamClientTransport>())
.run_if(resource_exists::<RenetClient>()),
);
}
}

impl SteamClientPlugin {
pub fn update_system(mut transport: ResMut<SteamClientTransport>, mut client: ResMut<RenetClient>) {
transport.update(&mut client);
}

pub fn send_packets(
mut transport: ResMut<SteamClientTransport>,
mut client: ResMut<RenetClient>,
mut transport_errors: EventWriter<SteamNetError>,
) {
if let Err(e) = transport.send_packets(&mut client) {
transport_errors.send(SteamNetError(e));
}
}

fn disconnect_on_exit(exit: EventReader<AppExit>, mut transport: ResMut<SteamClientTransport>) {
if !exit.is_empty() && !transport.is_disconnected() {
transport.disconnect(false);
}
}
}

pub fn client_connected() -> impl FnMut(Option<Res<SteamClientTransport>>) -> bool {
|transport| match transport {
Some(transport) => transport.is_connected(),
None => false,
}
}

pub fn client_diconnected() -> impl FnMut(Option<Res<SteamClientTransport>>) -> bool {
|transport| match transport {
Some(transport) => transport.is_disconnected(),
None => true,
}
}

pub fn client_connecting() -> impl FnMut(Option<Res<SteamClientTransport>>) -> bool {
|transport| match transport {
Some(transport) => transport.is_connecting(),
None => false,
}
}

pub fn client_just_connected() -> impl FnMut(Local<bool>, Option<Res<SteamClientTransport>>) -> bool {
|mut last_connected: Local<bool>, transport| {
let Some(transport) = transport else {
return false;
};

let connected = transport.is_connected();
let just_connected = !*last_connected && connected;
*last_connected = connected;
just_connected
}
}

pub fn client_just_diconnected() -> impl FnMut(Local<bool>, Option<Res<SteamClientTransport>>) -> bool {
|mut last_disconnected: Local<bool>, transport| {
let Some(transport) = transport else {
return true;
};

let disconnected = transport.is_disconnected();
let just_disconnected = !*last_disconnected && disconnected;
*last_disconnected = disconnected;
just_disconnected
}
}
2 changes: 1 addition & 1 deletion renet_steam/examples/echo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ fn run_client(steam_client: Client<ClientManager>, single: SingleClient, server_
last_updated = now;

client.update(duration);
transport.update(duration, &mut client);
transport.update(&mut client);

if transport.is_connected() {
match stdin_channel.try_recv() {
Expand Down
54 changes: 32 additions & 22 deletions renet_steam/src/client.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::time::Duration;

use super::MAX_MESSAGE_BATCH_SIZE;
use renet::RenetClient;
use steamworks::{
Expand All @@ -11,7 +9,7 @@ use steamworks::{
#[cfg_attr(feature = "bevy", derive(bevy_ecs::system::Resource))]
pub struct SteamClientTransport {
networking_sockets: NetworkingSockets<ClientManager>,
connection: NetConnection<ClientManager>,
connection: Option<NetConnection<ClientManager>>,
}

impl SteamClientTransport {
Expand All @@ -24,7 +22,7 @@ impl SteamClientTransport {
.connect_p2p(NetworkingIdentity::new_steam_id(*steam_id), 0, options)?;
Ok(Self {
networking_sockets,
connection,
connection: Some(connection),
})
}

Expand All @@ -47,17 +45,26 @@ impl SteamClientTransport {
}

pub fn connection_state(&self) -> NetworkingConnectionState {
if let Ok(info) = self.networking_sockets.get_connection_info(&self.connection) {
if let Ok(state) = info.state() {
return state;
}
}
let Some(connection) = &self.connection else {
return NetworkingConnectionState::ClosedByPeer;
};

let Ok(info) = self.networking_sockets.get_connection_info(connection) else {
return NetworkingConnectionState::None;
};

NetworkingConnectionState::None
match info.state() {
Ok(state) => state,
Err(_) => NetworkingConnectionState::None,
}
}

pub fn disconnect_reason(&self) -> Option<NetConnectionEnd> {
if let Ok(info) = self.networking_sockets.get_connection_info(&self.connection) {
let Some(connection) = &self.connection else {
return Some(NetConnectionEnd::AppGeneric);
};

if let Ok(info) = self.networking_sockets.get_connection_info(connection) {
return info.end_reason();
}

Expand All @@ -68,20 +75,22 @@ impl SteamClientTransport {
steam_client.user().steam_id().raw()
}

pub fn disconnect(self, send_last_packets: bool) {
self.connection.close(
steamworks::networking_types::NetConnectionEnd::AppGeneric,
Some("Disconnecting from server"),
send_last_packets,
);
pub fn disconnect(&mut self, send_last_packets: bool) {
if let Some(connection) = self.connection.take() {
connection.close(NetConnectionEnd::AppGeneric, Some("Disconnecting from server"), send_last_packets);
}
}

pub fn update(&mut self, _duration: Duration, client: &mut RenetClient) {
if !self.is_connected() {
pub fn update(&mut self, client: &mut RenetClient) {
if self.is_disconnected() {
if self.connection.is_some() {
self.disconnect(false);
}
return;
};

let messages = self.connection.receive_messages(MAX_MESSAGE_BATCH_SIZE);
let connection = self.connection.as_mut().unwrap();
let messages = connection.receive_messages(MAX_MESSAGE_BATCH_SIZE);
messages.iter().for_each(|message| {
client.process_packet(message.data());
});
Expand All @@ -96,11 +105,12 @@ impl SteamClientTransport {
return Ok(());
}

let connection = self.connection.as_mut().unwrap();
let packets = client.get_packets_to_send();
for packet in packets {
self.connection.send_message(&packet, SendFlags::UNRELIABLE)?;
connection.send_message(&packet, SendFlags::UNRELIABLE)?;
}

self.connection.flush_messages()
connection.flush_messages()
}
}
3 changes: 3 additions & 0 deletions renet_steam/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ mod server;

pub use client::SteamClientTransport;
pub use server::SteamServerTransport;

#[doc(hidden)]
pub use steamworks;

0 comments on commit 68b8f7f

Please sign in to comment.