use crate::errors::NetworkError;
use crate::server::ClientId;
use bevy::prelude::*;
use tokio::net::TcpStream;
#[derive(Debug)]
pub(crate) struct IncomingConnection {
pub(crate) socket: TcpStream,
}
#[derive(Debug, Event, Message)]
pub enum NetworkEvent {
Connected(ClientId),
Disconnected(ClientId),
Error(NetworkError),
}
#[derive(Debug, Clone)]
pub struct Payload {
pub package: String,
pub subpackage: Option<String>,
pub data: Option<String>,
}
#[derive(Debug, Clone)]
pub enum Frame {
Text(String),
GMCP(Payload),
Negotiation { command: u8, option: u8 },
Subnegotiation { option: u8, data: Vec<u8> },
Raw(Vec<u8>),
IAC(u8),
}
#[deprecated(note = "bevy renamed events to messages; this crate now calls its payloads Frames.")]
pub type Message = Frame;
impl From<&str> for Frame {
fn from(s: &str) -> Self {
Frame::Text(s.into())
}
}
impl From<String> for Frame {
fn from(s: String) -> Self {
Frame::Text(s)
}
}
impl From<Vec<u8>> for Frame {
fn from(v: Vec<u8>) -> Self {
Frame::Raw(v)
}
}
impl From<Payload> for Frame {
fn from(payload: Payload) -> Self {
Frame::GMCP(payload)
}
}
#[derive(Debug, Event, Message, Clone)]
pub struct Inbox {
pub from: ClientId,
pub content: Frame,
}
#[derive(Debug, Event, Message, Clone)]
pub struct Outbox {
pub to: ClientId,
pub content: Frame,
}
pub trait OutboxWriterExt {
fn write_text(&mut self, to: ClientId, text: impl Into<String>);
fn write_gmcp(&mut self, to: ClientId, payload: Payload);
fn write_negotiation(&mut self, to: ClientId, command: u8, option: u8);
fn write_subnegotiation(&mut self, to: ClientId, option: u8, data: impl Into<Vec<u8>>);
fn write_raw(&mut self, to: ClientId, data: impl Into<Vec<u8>>);
}
impl OutboxWriterExt for MessageWriter<'_, Outbox> {
fn write_text(&mut self, to: ClientId, text: impl Into<String>) {
self.write(Outbox {
to,
content: Frame::Text(text.into()),
});
}
fn write_gmcp(&mut self, to: ClientId, payload: Payload) {
self.write(Outbox {
to,
content: Frame::GMCP(payload),
});
}
fn write_negotiation(&mut self, to: ClientId, command: u8, option: u8) {
self.write(Outbox {
to,
content: Frame::Negotiation { command, option },
});
}
fn write_subnegotiation(&mut self, to: ClientId, option: u8, data: impl Into<Vec<u8>>) {
self.write(Outbox {
to,
content: Frame::Subnegotiation {
option,
data: data.into(),
},
});
}
fn write_raw(&mut self, to: ClientId, data: impl Into<Vec<u8>>) {
self.write(Outbox {
to,
content: Frame::Raw(data.into()),
});
}
}