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