bevnet 0.1.0

A library for networking in Bevy.
Documentation
use bevnet::{
    impl_packet, AppClientNetwork, AppServerNetwork, ClientConnection, ClientListener,
    ClientNetworkPlugin, PacketEvent, ServerConnection, ServerNetworkPlugin,
};
use bevy::prelude::*;
use serde::{Deserialize, Serialize};

/// A ping packet.
#[derive(Serialize, Deserialize)]
pub struct PingPacket;
impl_packet!(PingPacket);

/// A pong packet.
#[derive(Serialize, Deserialize)]
pub struct PongPacket;
impl_packet!(PongPacket);

/// Launch the server.
fn start_server(mut commands: Commands, keys: Res<Input<KeyCode>>) {
    if keys.just_pressed(KeyCode::B) {
        println!("Starting server...");
        match ClientListener::bind("127.0.0.1:8000") {
            Ok(listener) => {
                println!("Listening on {}", listener.address());
                commands.insert_resource(listener);
            }
            Err(e) => println!("Failed to bind: {}", e),
        }
    }
}

/// Show when a client connects.
fn client_connected(connection: Query<(Entity, &ClientConnection), Added<ClientConnection>>) {
    for (entity, connection) in connection.iter() {
        println!("Client connected: {} as {:?}", connection.address(), entity);
    }
}

/// Show when a client disconnects.
fn client_disconnected(mut removed: RemovedComponents<ClientConnection>) {
    for entity in removed.iter() {
        println!("Client disconnected: {:?}", entity);
    }
}

/// Receive the ping packets.
fn receive_ping(mut events: EventReader<PacketEvent<PingPacket>>) {
    for PacketEvent { connection, .. } in events.iter() {
        println!("Received ping from {}", connection.address());
        connection.send(PongPacket);
        println!("Response sent!");
    }
}

/// Connect the client to the server.
fn connect(mut commands: Commands, keys: Res<Input<KeyCode>>) {
    if keys.just_pressed(KeyCode::C) {
        println!("Connecting...");
        match ServerConnection::connect("127.0.0.1:8000") {
            Ok(connection) => {
                println!("Connected to {}", connection.address());
                commands.insert_resource(connection);
            }
            Err(e) => println!("Failed to connect: {}", e),
        }
    }
}

/// Receive the pong packets.
fn receive_pong(mut events: EventReader<PongPacket>) {
    for _ in events.iter() {
        println!("Received pong!");
    }
}

/// Send a ping packet to the server.
fn send_ping(keys: Res<Input<KeyCode>>, connection: Res<ServerConnection>) {
    if keys.just_pressed(KeyCode::P) {
        connection.send(PingPacket);
        println!("Ping sent!");
    }
}

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_plugin(ServerNetworkPlugin)
        .add_system(start_server)
        .add_system(client_connected)
        .add_system(client_disconnected)
        .add_system(receive_ping)
        .register_server_packet::<PingPacket>()
        .add_plugin(ClientNetworkPlugin)
        .add_system(connect)
        .add_system(send_ping.run_if(resource_exists::<ServerConnection>()))
        .add_system(receive_pong)
        .register_client_packet::<PongPacket>()
        .run();
}