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