use crate::message_c2s::{ MessageC2SAuthenticateAndBeamOut, MessageC2SChat, MessageC2SGoodbye, MessageC2SHello, MessageC2SInput, MessageC2SModuleDetach, MessageC2SModuleGrabBegin, MessageC2SModuleGrabEnd, MessageC2SMouseInput, MessageC2SPing, }; use crate::message_s2c::{ MessageS2CChat, MessageS2CGoodbye, MessageS2CHello, MessageS2CModuleAdd, MessageS2CModuleRemove, MessageS2CModuleTreeUpdate, MessageS2CModulesUpdate, MessageS2CPlanetData, MessageS2CPlayersUpdate, MessageS2CPong, }; use crate::planet::PlanetType; use crate::starkingdoms_protocol::PacketWrapper; use protobuf::{Enum, Message}; use std::error::Error; include!(concat!(env!("OUT_DIR"), "/protos/mod.rs")); pub const PROTOCOL_VERSION: u32 = 6; pub mod api; #[derive(Debug)] pub enum MessageC2S { Hello(MessageC2SHello), Goodbye(MessageC2SGoodbye), Chat(MessageC2SChat), Ping(MessageC2SPing), Input(MessageC2SInput), AuthenticateAndBeamOut(MessageC2SAuthenticateAndBeamOut), MouseInput(MessageC2SMouseInput), ModuleGrabBegin(MessageC2SModuleGrabBegin), ModuleGrabEnd(MessageC2SModuleGrabEnd), ModuleDetach(MessageC2SModuleDetach), } #[derive(Debug)] pub enum MessageS2C { Hello(MessageS2CHello), Goodbye(MessageS2CGoodbye), Chat(MessageS2CChat), Pong(MessageS2CPong), PlayersUpdate(MessageS2CPlayersUpdate), PlanetData(MessageS2CPlanetData), ModulesUpdate(MessageS2CModulesUpdate), ModuleTreeUpdate(MessageS2CModuleTreeUpdate), ModuleAdd(MessageS2CModuleAdd), ModuleRemove(MessageS2CModuleRemove), } impl TryFrom<&[u8]> for MessageC2S { type Error = Box; fn try_from(value: &[u8]) -> Result { let pkt = 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 if _id == message_c2s::message_c2smouse_input::Packet_info::type_.value() as i64 => { MessageC2S::MouseInput(MessageC2SMouseInput::parse_from_bytes(&pkt.packet_data)?) } _id if _id == message_c2s::message_c2smodule_grab_begin::Packet_info::type_.value() as i64 => { MessageC2S::ModuleGrabBegin(MessageC2SModuleGrabBegin::parse_from_bytes( &pkt.packet_data, )?) } _id if _id == message_c2s::message_c2smodule_grab_end::Packet_info::type_.value() as i64 => { MessageC2S::ModuleGrabEnd(MessageC2SModuleGrabEnd::parse_from_bytes( &pkt.packet_data, )?) } _id if _id == message_c2s::message_c2smodule_detach::Packet_info::type_.value() as i64 => { MessageC2S::ModuleDetach(MessageC2SModuleDetach::parse_from_bytes( &pkt.packet_data, )?) } _id => { return Err(format!("Unrecognized C2S packet {}", _id).into()); } }; Ok(deser_pkt) } } impl TryInto> for MessageC2S { type Error = Box; fn try_into(self) -> Result, 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()?, ), MessageC2S::MouseInput(p) => ( message_c2s::message_c2smouse_input::Packet_info::type_.value(), p.write_to_bytes()?, ), MessageC2S::ModuleGrabBegin(p) => ( message_c2s::message_c2smodule_grab_begin::Packet_info::type_.value(), p.write_to_bytes()?, ), MessageC2S::ModuleGrabEnd(p) => ( message_c2s::message_c2smodule_grab_end::Packet_info::type_.value(), p.write_to_bytes()?, ), MessageC2S::ModuleDetach(p) => ( message_c2s::message_c2smodule_detach::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; fn try_from(value: &[u8]) -> Result { 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)?) } _id if _id == message_s2c::message_s2cmodules_update::Packet_info::type_.value() as i64 => { MessageS2C::ModulesUpdate(MessageS2CModulesUpdate::parse_from_bytes( &pkt.packet_data, )?) } _id if _id == message_s2c::message_s2cmodule_tree_update::Packet_info::type_.value() as i64 => { MessageS2C::ModuleTreeUpdate(MessageS2CModuleTreeUpdate::parse_from_bytes( &pkt.packet_data, )?) } _id if _id == message_s2c::message_s2cmodule_add::Packet_info::type_.value() as i64 => { MessageS2C::ModuleAdd(MessageS2CModuleAdd::parse_from_bytes(&pkt.packet_data)?) } _id if _id == message_s2c::message_s2cmodule_remove::Packet_info::type_.value() as i64 => { MessageS2C::ModuleRemove(MessageS2CModuleRemove::parse_from_bytes( &pkt.packet_data, )?) } _ => { return Err("Not a S2C packet".into()); } }; Ok(deser_pkt) } } impl TryInto> for MessageS2C { type Error = Box; fn try_into(self) -> Result, 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()?, ), MessageS2C::ModulesUpdate(p) => ( message_s2c::message_s2cmodules_update::Packet_info::type_.value(), p.write_to_bytes()?, ), MessageS2C::ModuleTreeUpdate(p) => ( message_s2c::message_s2cmodule_tree_update::Packet_info::type_.value(), p.write_to_bytes()?, ), MessageS2C::ModuleAdd(p) => ( message_s2c::message_s2cmodule_add::Packet_info::type_.value(), p.write_to_bytes()?, ), MessageS2C::ModuleRemove(p) => ( message_s2c::message_s2cmodule_remove::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 PlanetType { pub fn as_texture_id(&self) -> String { match self { PlanetType::Earth => "earth".to_string(), PlanetType::Moon => "moon".to_string(), PlanetType::Mars => "mars".to_string(), PlanetType::UNKNOWN => "missing".to_string(), } } }