use grubbnet::{packet::PacketBody, PacketRecipient, Result, Server, ServerEvent, Token};
use std::collections::HashMap;
#[derive(serde::Serialize, serde::Deserialize, Clone)]
pub struct PingPacket {
pub msg: String,
}
impl PacketBody for PingPacket {
fn box_clone(&self) -> Box<dyn PacketBody> {
Box::new((*self).clone())
}
fn serialize(&self) -> Result<Vec<u8>> {
panic!("Attempted to serialize a client-only packet!");
}
fn deserialize(data: &[u8]) -> Result<Self> {
match bincode::config().big_endian().deserialize::<Self>(data) {
Ok(p) => Ok(p),
Err(_e) => Err(grubbnet::Error::InvalidData),
}
}
fn id(&self) -> u8 {
0x00
}
}
#[derive(serde::Serialize, serde::Deserialize, Clone)]
pub struct PongPacket {
pub msg: String,
}
impl PacketBody for PongPacket {
fn box_clone(&self) -> Box<dyn PacketBody> {
Box::new((*self).clone())
}
fn serialize(&self) -> Result<Vec<u8>> {
match bincode::config().big_endian().serialize::<Self>(&self) {
Ok(d) => Ok(d),
Err(_e) => Err(grubbnet::Error::InvalidData),
}
}
fn deserialize(_data: &[u8]) -> Result<Self> {
panic!("Attempted to deserialize a server-only packet!");
}
fn id(&self) -> u8 {
0x00
}
}
fn main() -> Result<()> {
let mut server = Server::host("127.0.0.1", 7667, 32)?;
println!("Hosting on 127.0.0.1:7667...");
let mut ping_counters: HashMap<Token, u32> = HashMap::new();
loop {
std::thread::sleep(std::time::Duration::from_millis(100));
for event in server.tick().iter() {
match event {
ServerEvent::ClientConnected(token, addr) => {
println!(
"Client {} connected from {} ({}/{})",
token.0,
addr.ip(),
server.num_connections(),
server.connection_limit(),
);
}
ServerEvent::ClientDisconnected(token) => {
println!("Client {} disconnected.", token.0);
}
ServerEvent::ConnectionRejected(addr) => {
println!(
"Rejected connection from {} (Connection limit reached)",
addr.ip(),
);
}
ServerEvent::ReceivedPacket(token, byte_count) => {
println!(
"Received packet from client {} ({} bytes)",
token.0, byte_count
);
}
ServerEvent::SentPacket(token, byte_count) => {
println!("Sent packet to client {} ({} bytes)", token.0, byte_count);
}
_ => eprintln!("Unhandled ServerEvent!"),
}
}
for (token, packet) in server.drain_incoming_packets().iter() {
match packet.header.id {
0x00 => {
let packet = PingPacket::deserialize(&packet.body);
println!("Got ping from client {}: {}", token.0, packet.unwrap().msg);
let counter = ping_counters.entry(*token).or_insert(0);
*counter += 1;
if *counter >= 5 {
println!("Client {} sent 5 pings. Kicking them.", token.0);
server.kick(*token)?;
ping_counters.remove_entry(token);
} else {
let pong = PongPacket {
msg: "Pong!".to_owned(),
};
server.send(PacketRecipient::Single(*token), pong);
}
}
_ => eprintln!("Unhandled packet! id: {}", packet.header.id),
}
}
}
Ok(())
}