use std::fmt::{Display, Formatter}; // StarKingdoms.IO, a browser game about drifting through space // Copyright (C) 2024 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 serde::{Deserialize, Serialize}; use crate::{PartType, PlanetType}; #[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, } #[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)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct ClientLoginPacket { pub username: String, pub save: Option, pub jwt: Option, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct SendMessagePacket { pub target: Option, pub content: String, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct PlayerInputPacket { pub up: bool, pub down: bool, pub left: bool, pub right: bool, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct PlayerMouseInputPacket { pub x: f32, pub y: f32, pub released: bool, pub button: ButtonType, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct RequestSavePacket { pub old_save: Option, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct SpecialDisconnectPacket {} #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct LoginResponsePacket { pub id: u32, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct SpawnPlayerPacket { pub id: u32, pub username: String, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct PlayerListPacket { pub players: Vec<(u32, String)>, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct PlanetPositionsPacket { pub planets: Vec<(u32, Planet)>, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct SpawnPlanetPacket { pub id: u32, pub planet: Planet, pub radius: f32, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct PartPositionsPacket { pub parts: Vec<(u32, Part)>, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct SpawnPartPacket { pub id: u32, pub part: Part, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct DespawnPartPacket { pub id: u32, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct PlayerLeavePacket { pub id: u32, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct MessagePacket { pub message_type: MessageType, pub actor: String, pub content: String, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct SaveEligibilityPacket { pub eligible: bool, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct SaveDataPacket { pub payload: String, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct EnergyUpdatePacket { pub amount: u32, pub max: u32, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[cfg_attr(feature = "bevy", derive(::bevy_ecs::event::Event))] pub struct OpenCraftingUiPacket { pub id: u32, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] #[serde(tag = "t", content = "c")] pub enum Packet { // serverbound ClientLogin(ClientLoginPacket), SendMessage(SendMessagePacket), PlayerInput(PlayerInputPacket), PlayerMouseInput(PlayerMouseInputPacket), RequestSave(RequestSavePacket), _SpecialDisconnect(SpecialDisconnectPacket), // clientbound LoginResponse(LoginResponsePacket), SpawnPlayer(SpawnPlayerPacket), PlayerList(PlayerListPacket), PlanetPositions(PlanetPositionsPacket), SpawnPlanet(SpawnPlanetPacket), PartPositions(PartPositionsPacket), SpawnPart(SpawnPartPacket), DespawnPart(DespawnPartPacket), PlayerLeave(PlayerLeavePacket), Message(MessagePacket), SaveEligibility(SaveEligibilityPacket), SaveData(SaveDataPacket), EnergyUpdate(EnergyUpdatePacket), OpenCraftingUi(OpenCraftingUiPacket), } #[cfg(feature = "bevy")] pub fn register_packet_events(world: &mut bevy_ecs::prelude::World) { bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); bevy_ecs::event::EventRegistry::register_event::(world); } impl From for String { fn from(val: Packet) -> Self { 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<&String> for Packet { type Error = MsgFromError; fn try_from(value: &String) -> Result { serde_json::from_str(value).map_err(MsgFromError::JSONError) } } impl TryFrom<&Vec> for Packet { type Error = MsgFromError; fn try_from(value: &Vec) -> Result { serde_json::from_slice(value).map_err(MsgFromError::JSONError) } }