bevnet/examples/ping_pong.rs
2023-04-27 00:39:27 +02:00

100 lines
3 KiB
Rust

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();
}