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,
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)]
pub struct ClientLoginPacket {
pub username: String,
pub save: Option,
pub jwt: Option,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct SendMessagePacket {
pub target: Option,
pub content: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct PlayerInputPacket {
pub up: bool,
pub down: bool,
pub left: bool,
pub right: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct PlayerMouseInputPacket {
pub x: f32,
pub y: f32,
pub released: bool,
pub button: ButtonType,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct RequestSavePacket {
pub old_save: Option,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct SpecialDisconnectPacket {}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct LoginResponsePacket {
pub id: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct SpawnPlayerPacket {
pub id: u32,
pub username: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct PlayerListPacket {
pub players: Vec<(u32, String)>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct PlanetPositionsPacket {
pub planets: Vec<(u32, Planet)>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct PartPositionsPacket {
pub parts: Vec<(u32, Part)>,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct SpawnPartPacket {
pub id: u32,
pub part: Part,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct DespawnPartPacket {
pub id: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct PlayerLeavePacket {
pub id: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct MessagePacket {
pub message_type: MessageType,
pub actor: String,
pub content: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct SaveEligibilityPacket {
pub eligible: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct SaveDataPacket {
pub payload: String,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct EnergyUpdatePacket {
pub amount: u32,
pub max: u32,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
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),
PartPositions(PartPositionsPacket),
SpawnPart(SpawnPartPacket),
DespawnPart(DespawnPartPacket),
PlayerLeave(PlayerLeavePacket),
Message(MessagePacket),
SaveEligibility(SaveEligibilityPacket),
SaveData(SaveDataPacket),
EnergyUpdate(EnergyUpdatePacket),
OpenCraftingUi(OpenCraftingUiPacket),
}
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)
}
}