classicube_relay/packet/
scope.rs1use std::io::Read;
2
3use byteorder::{ReadBytesExt, WriteBytesExt};
4
5#[derive(Debug, thiserror::Error)]
6pub enum ScopeError {
7 #[error("invalid scope {:?} with extra {:?}", kind, extra)]
8 InvalidScope { kind: u8, extra: u8 },
9
10 #[error(transparent)]
11 Io(#[from] std::io::Error),
12}
13type Result<T> = std::result::Result<T, ScopeError>;
14
15#[derive(Debug, Clone, PartialEq, Eq)]
19pub enum Scope {
20 Player(PlayerScope),
22
23 Map(MapScope),
25
26 Server(ServerScope),
28}
29impl Scope {
30 pub fn kind(&self) -> u8 {
31 match self {
32 Scope::Player { .. } => 0,
33 Scope::Map { .. } => 1,
34 Scope::Server { .. } => 2,
35 }
36 }
37
38 pub fn encode(&self) -> Result<Vec<u8>> {
39 let mut data = Vec::with_capacity(2);
40
41 data.write_u8(self.kind())?;
42
43 match self {
44 Scope::Player(PlayerScope { player_id }) => {
45 data.write_u8(*player_id)?;
46 }
47
48 Scope::Map(MapScope { have_plugin }) => {
49 data.write_u8(if *have_plugin { 0b1000_0000 } else { 0 })?;
50 }
51 Scope::Server(ServerScope { have_plugin }) => {
52 data.write_u8(if *have_plugin { 0b1000_0000 } else { 0 })?;
53 }
54 }
55
56 Ok(data)
57 }
58
59 pub(crate) fn decode(data_stream: &mut impl Read) -> Result<Self> {
60 let kind = data_stream.read_u8()?;
61 let extra = data_stream.read_u8()?;
62
63 let scope = match kind {
64 0 => Scope::Player(PlayerScope { player_id: extra }),
65
66 1 => {
67 let have_plugin = (extra & 0b1000_0000) != 0;
68 Scope::Map(MapScope { have_plugin })
69 }
70
71 2 => {
72 let have_plugin = (extra & 0b1000_0000) != 0;
73 Scope::Server(ServerScope { have_plugin })
74 }
75
76 _ => {
77 return Err(ScopeError::InvalidScope { kind, extra });
78 }
79 };
80
81 Ok(scope)
82 }
83}
84impl From<PlayerScope> for Scope {
85 fn from(scope: PlayerScope) -> Self {
86 Self::Player(scope)
87 }
88}
89impl From<MapScope> for Scope {
90 fn from(scope: MapScope) -> Self {
91 Self::Map(scope)
92 }
93}
94impl From<ServerScope> for Scope {
95 fn from(scope: ServerScope) -> Self {
96 Self::Server(scope)
97 }
98}
99
100#[derive(Debug, Clone, PartialEq, Eq)]
102pub struct PlayerScope {
103 pub player_id: u8,
107}
108impl PlayerScope {
109 pub fn new(player_id: u8) -> Self {
110 Self { player_id }
111 }
112}
113
114#[derive(Debug, Default, Clone, PartialEq, Eq)]
116pub struct MapScope {
117 pub have_plugin: bool,
121}
122
123#[derive(Debug, Default, Clone, PartialEq, Eq)]
125pub struct ServerScope {
126 pub have_plugin: bool,
130}