use std::fmt::{Display, Formatter}; // StarKingdoms.IO, a browser game about drifting through space // Copyright (C) 2023 ghostly_zsh, TerraMaster85, core // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . use crate::component::{PartType, PlanetType}; use bevy_tungstenite_stk::tungstenite::Message; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct ProtoTransform { pub x: f32, pub y: f32, pub rot: f32, } #[macro_export] macro_rules! proto_transform { ($e:expr) => { $crate::packet::ProtoTransform { x: $e.translation.x, y: $e.translation.y, rot: $e.rotation.to_euler(bevy::math::EulerRot::ZYX).0, } }; } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Planet { pub planet_type: PlanetType, pub transform: ProtoTransform, pub radius: f32, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct Part { pub part_type: PartType, pub transform: ProtoTransform, pub flags: ProtoPartFlags, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct ProtoPartFlags { pub attached: bool, } #[macro_export] macro_rules! proto_part_flags { ($e:expr) => { $crate::packet::ProtoPartFlags { attached: $e.attached, } }; } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub enum MessageType { Server, Error, Chat, Direct, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub enum ButtonType { Left, Middle, Right, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(tag = "t", content = "c")] pub enum Packet { // serverbound ClientLogin { username: String, save: Option, jwt: Option, }, SendMessage { target: Option, content: String, }, PlayerInput { up: bool, down: bool, left: bool, right: bool, }, PlayerMouseInput { x: f32, y: f32, released: bool, button: ButtonType, }, RequestSave {}, _SpecialDisconnect {}, // clientbound SpawnPlayer { id: u32, username: String, }, PlayerList { players: Vec<(u32, String)>, }, PlanetPositions { planets: Vec<(u32, Planet)>, }, PartPositions { parts: Vec<(u32, Part)>, }, SpawnPart { id: u32, part: Part, }, DespawnPart { id: u32, }, PlayerLeave { id: u32, }, Message { message_type: MessageType, actor: String, content: String, }, SaveEligibility { eligible: bool, }, SaveData { payload: String, }, } impl From for Message { fn from(val: Packet) -> Self { Message::Text(serde_json::to_string(&val).expect("failed to serialize packet to json")) } } #[derive(Debug)] pub enum MsgFromError { InvalidMessageType, JSONError(serde_json::Error), } impl Display for MsgFromError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { write!(f, "{:?}", self) } } impl TryFrom<&Message> for Packet { type Error = MsgFromError; fn try_from(value: &Message) -> Result { match value { Message::Text(s) => serde_json::from_str(s).map_err(MsgFromError::JSONError), Message::Binary(b) => serde_json::from_slice(b).map_err(MsgFromError::JSONError), Message::Close(_) => Ok(Packet::_SpecialDisconnect {}), Message::Frame(_) | Message::Pong(_) | Message::Ping(_) => { Err(MsgFromError::InvalidMessageType) } } } }