From 49192dbb98e0ab1f2a66b4786fac86d63f69be64 Mon Sep 17 00:00:00 2001 From: "1992414357@qq.com" <1992414357@qq.com> Date: Mon, 9 Jun 2025 01:44:36 +0800 Subject: 重构所有部分 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/data/message/enums.rs | 154 ++++++++++++++++++++++++++++++++++++ core/src/data/message/implements.rs | 15 ++++ core/src/data/message/mod.rs | 3 + core/src/data/message/traits.rs | 67 ++++++++++++++++ 4 files changed, 239 insertions(+) create mode 100644 core/src/data/message/enums.rs create mode 100644 core/src/data/message/implements.rs create mode 100644 core/src/data/message/mod.rs create mode 100644 core/src/data/message/traits.rs (limited to 'core/src/data/message') diff --git a/core/src/data/message/enums.rs b/core/src/data/message/enums.rs new file mode 100644 index 0000000..4150b63 --- /dev/null +++ b/core/src/data/message/enums.rs @@ -0,0 +1,154 @@ +use crate::data::player::structs::Player; +use bincode::{Decode, Encode}; +use crate::data::game::types::GameInfo; + +/// Control messages. +/// Messages sent from controller to game pad_client after establishing persistent connection +#[derive(Default, Encode, Decode, PartialEq, Debug, Clone)] +pub enum ControlMessage { + /// Plain message containing a string + /// The message will be handed over to the game for its own processing + Msg(String), + + /// Press event + /// Indicates that a button has been pressed + Pressed(u8), + + /// Release event + /// Indicates that a button has been released + Released(u8), + + /// Axis input + /// Indicates that the value of an axis has been changed + Axis(u8, f64), + + /// Directional input + /// Indicates that the value of a direction has been changed + Dir(u8, (f64, f64)), + + /// Exit command + /// Sends a disconnect request to the pad_server + Exit, + + #[default] + /// Error state + Err, + + /// Indicates the termination message, which is the final message in a long-lived connection. + End +} + +/// Game messages. +/// Messages sent from game pad_client to controller after establishing persistent connection +#[derive(Default, Encode, Decode, PartialEq, Debug, Clone)] +pub enum GameMessage { + /// Event trigger + /// Sends an event to the controller; if skins are enabled, this will trigger corresponding animations, sounds, vibrations, etc. + EventTrigger(u8), + + /// Plain message containing a string + /// The message will be handed over to the controller for its own processing + Msg(String), + + /// Disconnect request + /// Notifies the pad_client that the connection will be terminated + LetExit(ExitReason), + + /// Error state + #[default] + Err, + + /// Indicates the termination message, which is the final message in a long-lived connection. + End +} + +/// Exit reasons. +/// Reason provided when requesting disconnection +#[derive(Default, Encode, Decode, PartialEq, Debug, Clone)] +pub enum ExitReason { + /// Normal exit + /// No specific reason, simply requesting to disconnect + Exit, + + /// Game has ended + GameOver, + + /// Server shutdown (normal) + ServerClosed, + + /// Kicked by pad_server + YouAreKicked, + + /// Account banned + YouAreBanned, + + /// Error state + #[default] + Err +} + +/// Connection messages. +/// Messages sent by pad_client when requesting pad_server connection +#[derive(Default, Encode, Decode, PartialEq, Debug, Clone)] +pub enum ConnectionMessage { + /// Requests to join the game + Join(Player), + + /// Request for game information + RequestGameInfos, + + /// Request for game layout configuration file + RequestLayoutConfigure, + + /// Request to download game skin assets + RequestSkinPackage, + + /// Ready state to establish persistent connection + Ready, + + /// Error state + #[default] + Err +} + +/// Connection Response. +/// Messages from pad_server responding to pad_client connection requests +#[derive(Default, Encode, Decode, PartialEq, Debug, Clone)] +pub enum ConnectionResponseMessage { + /// Game information data + GameInfos(GameInfo), + + /// Rejection with reason + Deny(JoinFailedMessage), + + /// Failure with reason + Fail(JoinFailedMessage), + + /// Approval confirmation + Ok, + + /// Welcome acknowledgment + Welcome, + + /// Error state + #[default] + Err +} + +/// Game Join Failure Information. +/// Reason provided when pad_client fails to join +#[derive(Default, Encode, Decode, PartialEq, Debug, Clone)] +pub enum JoinFailedMessage { + /// Game already contains identical player + ContainIdenticalPlayer, + + /// Player is banned + PlayerBanned, + + /// Game is locked, no further joins allowed + GameLocked, + + /// Unknown error + #[default] + UnknownError +} \ No newline at end of file diff --git a/core/src/data/message/implements.rs b/core/src/data/message/implements.rs new file mode 100644 index 0000000..2d5bae8 --- /dev/null +++ b/core/src/data/message/implements.rs @@ -0,0 +1,15 @@ +use crate::data::message::enums::{ConnectionResponseMessage, JoinFailedMessage, ConnectionMessage, ControlMessage, ExitReason, GameMessage}; +use crate::data::message::traits::MessageEncoder; + +#[macro_export] +macro_rules! encoder { + ($($msg:ident),+) => { + $( + impl MessageEncoder<$msg> for $msg {} + )+ + }; +} + +encoder!( + ControlMessage, GameMessage, ExitReason, ConnectionMessage, ConnectionResponseMessage, JoinFailedMessage +); \ No newline at end of file diff --git a/core/src/data/message/mod.rs b/core/src/data/message/mod.rs new file mode 100644 index 0000000..96fdd73 --- /dev/null +++ b/core/src/data/message/mod.rs @@ -0,0 +1,3 @@ +pub mod enums; +pub mod implements; +pub mod traits; \ No newline at end of file diff --git a/core/src/data/message/traits.rs b/core/src/data/message/traits.rs new file mode 100644 index 0000000..c4b3af4 --- /dev/null +++ b/core/src/data/message/traits.rs @@ -0,0 +1,67 @@ +use std::collections::{HashMap, VecDeque}; +use std::fmt::Debug; +use std::hash::Hash; +use bincode::{Decode, Encode}; +use crate::data::{BINCODE_CONFIG, BINCODE_CONVERT_FAILED}; +use crate::service::service_types::ServiceType; + +/// Message Manager +/// Provides the ability to store and retrieve messages from a VecDeque +pub trait MessageManager +where Key: Eq + Hash { + fn borrow_received_list_mut(&mut self) -> &mut HashMap<(ServiceType, Key), VecDeque>; + + fn borrow_send_list_mut(&mut self) -> &mut HashMap<(ServiceType, Key), VecDeque>; + + fn send(&mut self, message: Out, key: Key, service: ServiceType) { + self.borrow_send_list_mut() + .entry((service, key)) + .or_insert_with(VecDeque::new) + .push_back(message); + } + + fn receive(&mut self, key: Key, service: ServiceType) -> Option { + self.borrow_received_list_mut() + .entry((service, key)) + .or_insert_with(VecDeque::new) + .pop_front() + } + + fn pop_from_send_list(&mut self, key: Key, service: ServiceType) -> Option { + self.borrow_send_list_mut() + .entry((service, key)) + .or_insert_with(VecDeque::new) + .pop_front() + } + + fn put_into_receive_list(&mut self, message: In, key: Key, service: ServiceType) { + self.borrow_received_list_mut() + .entry((service, key)) + .or_insert_with(VecDeque::new) + .push_back(message); + } +} + +/// Message Encoder +/// Provides the ability to encode messages into binary data or decode them from binary data +pub trait MessageEncoder + Default + Debug> { + fn err_result_decode () -> M { + M::default() + } + + fn err_result_encode () -> Vec { + BINCODE_CONVERT_FAILED + } + + fn en(&self) -> Vec where Self : Encode { + bincode::encode_to_vec(self, BINCODE_CONFIG) + .unwrap_or_else(|_| Self::err_result_encode()) + } + + fn de(encoded : Vec) -> M { + match bincode::decode_from_slice(&encoded[..], BINCODE_CONFIG) { + Ok((decoded, _)) => decoded, + Err(_) => Self::err_result_decode() + } + } +} \ No newline at end of file -- cgit