1+ use anyhow:: anyhow;
12use base:: ItemStack ;
23
34pub mod codec;
@@ -23,32 +24,173 @@ pub enum ProtocolVersion {
2324 V1_16_2 ,
2425}
2526
26- /// Denotes a type which may be treated as a packet.
27- ///
28- /// If you want to store arbitrary packets (e.g. for sending
29- /// over a channel), use [`Packet`](crate::Packet) instead,
30- /// as it does not require boxing.
31- pub trait PacketTrait : Readable + Writeable {
32- /// Returns the ID of this packet for the given protocol version.
33- fn id ( version : ProtocolVersion ) -> u32
34- where
35- Self : Sized ;
36- }
37-
38- /// Current state of the connection.
39- /// This state is updated during the login
40- /// sequence. See wiki.vg.
27+ /// A protocol state.
4128#[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
42- pub enum Stage {
29+ pub enum ProtocolState {
4330 Handshake ,
4431 Status ,
4532 Login ,
4633 Play ,
4734}
4835
49- /// Direction in which a packet is sent.
50- #[ derive( Copy , Clone , Debug , PartialEq , Eq , Hash ) ]
51- pub enum PacketDirection {
52- Clientbound ,
53- Serverbound ,
36+ /// Reads an arbitrary packet sent by a client based on a dynamically-updated
37+ /// protocol state. As opposed to `MinecraftCodec`, this struct does not type-encode
38+ /// the current protocol state using generics.
39+ ///
40+ /// This is a wrapper around a `MinecraftCodec` but more useful in certain sitations
41+ /// (e.g. when writing a proxy.)
42+ pub struct ClientPacketCodec {
43+ state : ProtocolState ,
44+ codec : MinecraftCodec ,
45+ }
46+
47+ impl ClientPacketCodec {
48+ pub fn new ( ) -> Self {
49+ Self {
50+ state : ProtocolState :: Handshake ,
51+ codec : MinecraftCodec :: new ( ) ,
52+ }
53+ }
54+
55+ pub fn set_state ( & mut self , state : ProtocolState ) {
56+ self . state = state
57+ }
58+
59+ /// Decodes a `ClientPacket` using the provided data.
60+ pub fn decode ( & mut self , data : & [ u8 ] ) -> anyhow:: Result < Option < ClientPacket > > {
61+ match self . state {
62+ ProtocolState :: Handshake => self
63+ . codec
64+ . decode :: < ClientHandshakePacket > ( data)
65+ . map ( |opt| opt. map ( ClientPacket :: from) ) ,
66+ ProtocolState :: Status => self
67+ . codec
68+ . decode :: < ClientStatusPacket > ( data)
69+ . map ( |opt| opt. map ( ClientPacket :: from) ) ,
70+ ProtocolState :: Login => self
71+ . codec
72+ . decode :: < ClientLoginPacket > ( data)
73+ . map ( |opt| opt. map ( ClientPacket :: from) ) ,
74+ ProtocolState :: Play => self
75+ . codec
76+ . decode :: < ClientPlayPacket > ( data)
77+ . map ( |opt| opt. map ( ClientPacket :: from) ) ,
78+ }
79+ }
80+
81+ /// Encodes a `ClientPacket` into a buffer.
82+ pub fn encode ( & mut self , packet : & ClientPacket , buffer : & mut Vec < u8 > ) {
83+ match packet {
84+ ClientPacket :: Handshake ( packet) => self . codec . encode ( packet, buffer) ,
85+ ClientPacket :: Status ( packet) => self . codec . encode ( packet, buffer) ,
86+ ClientPacket :: Login ( packet) => self . codec . encode ( packet, buffer) ,
87+ ClientPacket :: Play ( packet) => self . codec . encode ( packet, buffer) ,
88+ }
89+ }
90+ }
91+
92+ /// Similar to `ClientPacketCodec` but for server-sent packets.
93+ pub struct ServerPacketCodec {
94+ state : ProtocolState ,
95+ codec : MinecraftCodec ,
96+ }
97+
98+ impl ServerPacketCodec {
99+ pub fn new ( ) -> Self {
100+ Self {
101+ state : ProtocolState :: Handshake ,
102+ codec : MinecraftCodec :: new ( ) ,
103+ }
104+ }
105+
106+ pub fn set_state ( & mut self , state : ProtocolState ) {
107+ self . state = state
108+ }
109+
110+ /// Decodes a `ServerPacket` using the provided data.
111+ pub fn decode ( & mut self , data : & [ u8 ] ) -> anyhow:: Result < Option < ServerPacket > > {
112+ match self . state {
113+ ProtocolState :: Handshake => Err ( anyhow ! ( "server sent data during handshake state" ) ) ,
114+ ProtocolState :: Status => self
115+ . codec
116+ . decode :: < ServerStatusPacket > ( data)
117+ . map ( |opt| opt. map ( ServerPacket :: from) ) ,
118+ ProtocolState :: Login => self
119+ . codec
120+ . decode :: < ServerLoginPacket > ( data)
121+ . map ( |opt| opt. map ( ServerPacket :: from) ) ,
122+ ProtocolState :: Play => self
123+ . codec
124+ . decode :: < ServerPlayPacket > ( data)
125+ . map ( |opt| opt. map ( ServerPacket :: from) ) ,
126+ }
127+ }
128+
129+ /// Encodes a `ServerPacket` into a buffer.
130+ pub fn encode ( & mut self , packet : & ServerPacket , buffer : & mut Vec < u8 > ) {
131+ match packet {
132+ ServerPacket :: Status ( packet) => self . codec . encode ( packet, buffer) ,
133+ ServerPacket :: Login ( packet) => self . codec . encode ( packet, buffer) ,
134+ ServerPacket :: Play ( packet) => self . codec . encode ( packet, buffer) ,
135+ }
136+ }
137+ }
138+
139+ /// A packet sent by the client from any one of the packet stages.
140+ #[ derive( Debug , Clone ) ]
141+ pub enum ClientPacket {
142+ Handshake ( ClientHandshakePacket ) ,
143+ Status ( ClientStatusPacket ) ,
144+ Login ( ClientLoginPacket ) ,
145+ Play ( ClientPlayPacket ) ,
146+ }
147+
148+ impl From < ClientHandshakePacket > for ClientPacket {
149+ fn from ( packet : ClientHandshakePacket ) -> Self {
150+ ClientPacket :: Handshake ( packet)
151+ }
152+ }
153+
154+ impl From < ClientStatusPacket > for ClientPacket {
155+ fn from ( packet : ClientStatusPacket ) -> Self {
156+ ClientPacket :: Status ( packet)
157+ }
158+ }
159+
160+ impl From < ClientLoginPacket > for ClientPacket {
161+ fn from ( packet : ClientLoginPacket ) -> Self {
162+ ClientPacket :: Login ( packet)
163+ }
164+ }
165+
166+ impl From < ClientPlayPacket > for ClientPacket {
167+ fn from ( packet : ClientPlayPacket ) -> Self {
168+ ClientPacket :: Play ( packet)
169+ }
170+ }
171+
172+ /// A packet sent by the server from any one of the packet stages.
173+ #[ derive( Debug , Clone ) ]
174+ pub enum ServerPacket {
175+ Status ( ServerStatusPacket ) ,
176+ Login ( ServerLoginPacket ) ,
177+ Play ( ServerPlayPacket ) ,
178+ }
179+
180+ impl From < ServerStatusPacket > for ServerPacket {
181+ fn from ( packet : ServerStatusPacket ) -> Self {
182+ ServerPacket :: Status ( packet)
183+ }
184+ }
185+
186+ impl From < ServerLoginPacket > for ServerPacket {
187+ fn from ( packet : ServerLoginPacket ) -> Self {
188+ ServerPacket :: Login ( packet)
189+ }
190+ }
191+
192+ impl From < ServerPlayPacket > for ServerPacket {
193+ fn from ( packet : ServerPlayPacket ) -> Self {
194+ ServerPacket :: Play ( packet)
195+ }
54196}
0 commit comments