use std::error::Error;
use protobuf::{Enum, Message};
use crate::message_c2s::{MessageC2SAuthenticateAndBeamOut, MessageC2SChat, MessageC2SGoodbye, MessageC2SHello, MessageC2SInput, MessageC2SPing};
use crate::message_s2c::{MessageS2CChat, MessageS2CGoodbye, MessageS2CHello, MessageS2CPlanetData, MessageS2CPlayersUpdate, MessageS2CPong};
use crate::planet::PlanetType;
use crate::starkingdoms_protocol::PacketWrapper;
include!(concat!(env!("OUT_DIR"), "/protos/mod.rs"));
pub const PROTOCOL_VERSION: u32 = 1;
#[derive(Debug)]
pub enum MessageC2S {
Hello(MessageC2SHello),
Goodbye(MessageC2SGoodbye),
Chat(MessageC2SChat),
Ping(MessageC2SPing),
Input(MessageC2SInput),
AuthenticateAndBeamOut(MessageC2SAuthenticateAndBeamOut)
}
#[derive(Debug)]
pub enum MessageS2C {
Hello(MessageS2CHello),
Goodbye(MessageS2CGoodbye),
Chat(MessageS2CChat),
Pong(MessageS2CPong),
PlayersUpdate(MessageS2CPlayersUpdate),
PlanetData(MessageS2CPlanetData)
}
impl TryFrom<&[u8]> for MessageC2S {
type Error = Box<dyn Error>;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let pkt = starkingdoms_protocol::PacketWrapper::parse_from_bytes(value)?;
let deser_pkt = match pkt.packet_id {
_id if _id == message_c2s::message_c2shello::Packet_info::type_.value() as i64 => {
MessageC2S::Hello(MessageC2SHello::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_c2s::message_c2sgoodbye::Packet_info::type_.value() as i64 => {
MessageC2S::Goodbye(MessageC2SGoodbye::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_c2s::message_c2schat::Packet_info::type_.value() as i64 => {
MessageC2S::Chat(MessageC2SChat::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_c2s::message_c2sping::Packet_info::type_.value() as i64 => {
MessageC2S::Ping(MessageC2SPing::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_c2s::message_c2sinput::Packet_info::type_.value() as i64 => {
MessageC2S::Input(MessageC2SInput::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_c2s::message_c2sauthenticate_and_beam_out::Packet_info::type_.value() as i64 => {
MessageC2S::AuthenticateAndBeamOut(MessageC2SAuthenticateAndBeamOut::parse_from_bytes(&pkt.packet_data)?)
}
_id => { return Err(format!("Unrecognized C2S packet {}", _id).into()); }
};
Ok(deser_pkt)
}
}
impl TryInto<Vec<u8>> for MessageC2S {
type Error = Box<dyn Error>;
fn try_into(self) -> Result<Vec<u8>, Self::Error> {
let (pkt_id, pkt_bytes) = match self {
MessageC2S::Hello(p) => {
(message_c2s::message_c2shello::Packet_info::type_.value(), p.write_to_bytes()?)
}
MessageC2S::Goodbye(p) => {
(message_c2s::message_c2sgoodbye::Packet_info::type_.value(), p.write_to_bytes()?)
}
MessageC2S::Chat(p) => {
(message_c2s::message_c2schat::Packet_info::type_.value(), p.write_to_bytes()?)
}
MessageC2S::Ping(p) => {
(message_c2s::message_c2sping::Packet_info::type_.value(), p.write_to_bytes()?)
}
MessageC2S::Input(p) => {
(message_c2s::message_c2sping::Packet_info::type_.value(), p.write_to_bytes()?)
},
MessageC2S::AuthenticateAndBeamOut(p) => {
(message_c2s::message_c2sauthenticate_and_beam_out::Packet_info::type_.value(), p.write_to_bytes()?)
}
};
let pkt = PacketWrapper {
packet_id: pkt_id as i64,
packet_data: pkt_bytes,
special_fields: Default::default(),
};
Ok(pkt.write_to_bytes()?)
}
}
impl TryFrom<&[u8]> for MessageS2C {
type Error = Box<dyn Error>;
fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
let pkt = PacketWrapper::parse_from_bytes(value)?;
let deser_pkt = match pkt.packet_id {
_id if _id == message_s2c::message_s2chello::Packet_info::type_.value() as i64 => {
MessageS2C::Hello(MessageS2CHello::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_s2c::message_s2cgoodbye::Packet_info::type_.value() as i64 => {
MessageS2C::Goodbye(MessageS2CGoodbye::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_s2c::message_s2cchat::Packet_info::type_.value() as i64 => {
MessageS2C::Chat(MessageS2CChat::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_s2c::message_s2cpong::Packet_info::type_.value() as i64 => {
MessageS2C::Pong(MessageS2CPong::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_s2c::message_s2cplayers_update::Packet_info::type_.value() as i64 => {
MessageS2C::PlayersUpdate(MessageS2CPlayersUpdate::parse_from_bytes(&pkt.packet_data)?)
},
_id if _id == message_s2c::message_s2cplanet_data::Packet_info::type_.value() as i64 => {
MessageS2C::PlanetData(MessageS2CPlanetData::parse_from_bytes(&pkt.packet_data)?)
},
_ => { return Err("Not a S2C packet".into()); }
};
Ok(deser_pkt)
}
}
impl TryInto<Vec<u8>> for MessageS2C {
type Error = Box<dyn Error>;
fn try_into(self) -> Result<Vec<u8>, Self::Error> {
let (pkt_id, pkt_bytes) = match self {
MessageS2C::Hello(p) => {
(message_s2c::message_s2chello::Packet_info::type_.value(), p.write_to_bytes()?)
}
MessageS2C::Goodbye(p) => {
(message_s2c::message_s2cgoodbye::Packet_info::type_.value(), p.write_to_bytes()?)
}
MessageS2C::Chat(p) => {
(message_s2c::message_s2cchat::Packet_info::type_.value(), p.write_to_bytes()?)
}
MessageS2C::Pong(p) => {
(message_s2c::message_s2cpong::Packet_info::type_.value(), p.write_to_bytes()?)
}
MessageS2C::PlayersUpdate(p) => {
(message_s2c::message_s2cplayers_update::Packet_info::type_.value(), p.write_to_bytes()?)
}
MessageS2C::PlanetData(p) => {
(message_s2c::message_s2cplanet_data::Packet_info::type_.value(), p.write_to_bytes()?)
}
};
let pkt = PacketWrapper {
packet_id: pkt_id as i64,
packet_data: pkt_bytes,
special_fields: Default::default(),
};
Ok(pkt.write_to_bytes()?)
}
}
impl planet::PlanetType {
pub fn as_texture_id(&self) -> String {
match self {
PlanetType::Earth => "earth".to_string(),
PlanetType::Moon => "moon".to_string()
}
}
}