Skip to main content

kojacoord_protocol/versions/v1_20_4/play/
mod.rs

1use bytes::{Buf, Bytes, BytesMut};
2
3use crate::codec::{Decode, Encode, PacketId};
4use crate::error::ProtocolError;
5use crate::types::VarInt;
6
7#[derive(Debug, Clone, PartialEq)]
8pub struct ServerboundAcceptTeleportation {
9    pub teleport_id: VarInt,
10}
11
12impl PacketId for ServerboundAcceptTeleportation {
13    fn packet_id(_ver: u32) -> u8 {
14        0x05
15    }
16}
17
18impl Encode for ServerboundAcceptTeleportation {
19    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
20        self.teleport_id.encode(dst)
21    }
22}
23
24impl Decode for ServerboundAcceptTeleportation {
25    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
26        Ok(Self {
27            teleport_id: VarInt::decode(src)?,
28        })
29    }
30}
31
32#[derive(Debug, Clone, PartialEq)]
33pub struct ServerboundClientInformation {
34    pub locale: String,
35
36    pub view_distance: i8,
37
38    pub chat_mode: VarInt,
39
40    pub chat_colors: bool,
41
42    pub displayed_skin_parts: u8,
43
44    pub main_hand: VarInt,
45
46    pub enable_text_filtering: bool,
47
48    pub allow_server_listings: bool,
49}
50
51impl PacketId for ServerboundClientInformation {
52    fn packet_id(_ver: u32) -> u8 {
53        0x09
54    }
55}
56
57impl Encode for ServerboundClientInformation {
58    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
59        self.locale.encode(dst)?;
60        self.view_distance.encode(dst)?;
61        self.chat_mode.encode(dst)?;
62        self.chat_colors.encode(dst)?;
63        self.displayed_skin_parts.encode(dst)?;
64        self.main_hand.encode(dst)?;
65        self.enable_text_filtering.encode(dst)?;
66        self.allow_server_listings.encode(dst)
67    }
68}
69
70impl Decode for ServerboundClientInformation {
71    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
72        Ok(Self {
73            locale: String::decode(src)?,
74            view_distance: i8::decode(src)?,
75            chat_mode: VarInt::decode(src)?,
76            chat_colors: bool::decode(src)?,
77            displayed_skin_parts: u8::decode(src)?,
78            main_hand: VarInt::decode(src)?,
79            enable_text_filtering: bool::decode(src)?,
80            allow_server_listings: bool::decode(src)?,
81        })
82    }
83}
84
85#[derive(Debug, Clone, PartialEq)]
86pub enum InteractAction {
87    Interact {
88        hand: VarInt,
89    },
90
91    Attack,
92
93    InteractAt {
94        target_x: f32,
95        target_y: f32,
96        target_z: f32,
97        hand: VarInt,
98    },
99}
100
101#[derive(Debug, Clone, PartialEq)]
102pub struct ServerboundInteract {
103    pub entity_id: VarInt,
104
105    pub action: InteractAction,
106
107    pub sneaking: bool,
108}
109
110impl PacketId for ServerboundInteract {
111    fn packet_id(_ver: u32) -> u8 {
112        0x13
113    }
114}
115
116impl Encode for ServerboundInteract {
117    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
118        self.entity_id.encode(dst)?;
119        match &self.action {
120            InteractAction::Interact { hand } => {
121                VarInt(0).encode(dst)?;
122                hand.encode(dst)?;
123            },
124            InteractAction::Attack => {
125                VarInt(1).encode(dst)?;
126            },
127            InteractAction::InteractAt {
128                target_x,
129                target_y,
130                target_z,
131                hand,
132            } => {
133                VarInt(2).encode(dst)?;
134                target_x.encode(dst)?;
135                target_y.encode(dst)?;
136                target_z.encode(dst)?;
137                hand.encode(dst)?;
138            },
139        }
140        self.sneaking.encode(dst)
141    }
142}
143
144impl Decode for ServerboundInteract {
145    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
146        let entity_id = VarInt::decode(src)?;
147        let action = match VarInt::decode(src)?.0 {
148            0 => InteractAction::Interact {
149                hand: VarInt::decode(src)?,
150            },
151            1 => InteractAction::Attack,
152            2 => InteractAction::InteractAt {
153                target_x: f32::decode(src)?,
154                target_y: f32::decode(src)?,
155                target_z: f32::decode(src)?,
156                hand: VarInt::decode(src)?,
157            },
158            _ => return Err(ProtocolError::UnexpectedEof),
159        };
160        let sneaking = bool::decode(src)?;
161        Ok(Self {
162            entity_id,
163            action,
164            sneaking,
165        })
166    }
167}
168
169#[derive(Debug, Clone, PartialEq)]
170pub struct ServerboundKeepAlive {
171    pub id: i64,
172}
173
174impl PacketId for ServerboundKeepAlive {
175    fn packet_id(_ver: u32) -> u8 {
176        0x18
177    }
178}
179
180impl Encode for ServerboundKeepAlive {
181    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
182        self.id.encode(dst)
183    }
184}
185
186impl Decode for ServerboundKeepAlive {
187    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
188        Ok(Self {
189            id: i64::decode(src)?,
190        })
191    }
192}
193
194#[derive(Debug, Clone, PartialEq)]
195pub struct ServerboundMovePlayerStatusOnly {
196    pub on_ground: bool,
197}
198
199impl PacketId for ServerboundMovePlayerStatusOnly {
200    fn packet_id(_ver: u32) -> u8 {
201        0x14
202    }
203}
204
205impl Encode for ServerboundMovePlayerStatusOnly {
206    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
207        self.on_ground.encode(dst)
208    }
209}
210
211impl Decode for ServerboundMovePlayerStatusOnly {
212    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
213        Ok(Self {
214            on_ground: bool::decode(src)?,
215        })
216    }
217}
218
219#[derive(Debug, Clone, PartialEq)]
220pub struct ServerboundMovePlayerPos {
221    pub x: f64,
222    pub feet_y: f64,
223    pub z: f64,
224    pub on_ground: bool,
225}
226
227impl PacketId for ServerboundMovePlayerPos {
228    fn packet_id(_ver: u32) -> u8 {
229        0x15
230    }
231}
232
233impl Encode for ServerboundMovePlayerPos {
234    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
235        self.x.encode(dst)?;
236        self.feet_y.encode(dst)?;
237        self.z.encode(dst)?;
238        self.on_ground.encode(dst)
239    }
240}
241
242impl Decode for ServerboundMovePlayerPos {
243    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
244        Ok(Self {
245            x: f64::decode(src)?,
246            feet_y: f64::decode(src)?,
247            z: f64::decode(src)?,
248            on_ground: bool::decode(src)?,
249        })
250    }
251}
252
253#[derive(Debug, Clone, PartialEq)]
254pub struct ServerboundMovePlayerRot {
255    pub yaw: f32,
256    pub pitch: f32,
257    pub on_ground: bool,
258}
259
260impl PacketId for ServerboundMovePlayerRot {
261    fn packet_id(_ver: u32) -> u8 {
262        0x16
263    }
264}
265
266impl Encode for ServerboundMovePlayerRot {
267    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
268        self.yaw.encode(dst)?;
269        self.pitch.encode(dst)?;
270        self.on_ground.encode(dst)
271    }
272}
273
274impl Decode for ServerboundMovePlayerRot {
275    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
276        Ok(Self {
277            yaw: f32::decode(src)?,
278            pitch: f32::decode(src)?,
279            on_ground: bool::decode(src)?,
280        })
281    }
282}
283
284#[derive(Debug, Clone, PartialEq)]
285pub struct ServerboundMovePlayerPosRot {
286    pub x: f64,
287    pub feet_y: f64,
288    pub z: f64,
289    pub yaw: f32,
290    pub pitch: f32,
291    pub on_ground: bool,
292}
293
294impl PacketId for ServerboundMovePlayerPosRot {
295    fn packet_id(_ver: u32) -> u8 {
296        0x17
297    }
298}
299
300impl Encode for ServerboundMovePlayerPosRot {
301    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
302        self.x.encode(dst)?;
303        self.feet_y.encode(dst)?;
304        self.z.encode(dst)?;
305        self.yaw.encode(dst)?;
306        self.pitch.encode(dst)?;
307        self.on_ground.encode(dst)
308    }
309}
310
311impl Decode for ServerboundMovePlayerPosRot {
312    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
313        Ok(Self {
314            x: f64::decode(src)?,
315            feet_y: f64::decode(src)?,
316            z: f64::decode(src)?,
317            yaw: f32::decode(src)?,
318            pitch: f32::decode(src)?,
319            on_ground: bool::decode(src)?,
320        })
321    }
322}
323
324#[derive(Debug, Clone, PartialEq)]
325pub struct ServerboundPluginMessage {
326    pub channel: String,
327    pub data: Vec<u8>,
328}
329
330impl PacketId for ServerboundPluginMessage {
331    fn packet_id(_ver: u32) -> u8 {
332        0x0F
333    }
334}
335
336impl Encode for ServerboundPluginMessage {
337    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
338        self.channel.encode(dst)?;
339        dst.extend_from_slice(&self.data);
340        Ok(())
341    }
342}
343
344impl Decode for ServerboundPluginMessage {
345    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
346        let channel = String::decode(src)?;
347        let data = src.copy_to_bytes(src.remaining()).to_vec();
348        Ok(Self { channel, data })
349    }
350}
351
352#[derive(Debug, Clone, PartialEq)]
353pub struct ServerboundPlayerAbilities {
354    pub flags: u8,
355}
356
357impl PacketId for ServerboundPlayerAbilities {
358    fn packet_id(_ver: u32) -> u8 {
359        0x22
360    }
361}
362
363impl Encode for ServerboundPlayerAbilities {
364    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
365        self.flags.encode(dst)
366    }
367}
368
369impl Decode for ServerboundPlayerAbilities {
370    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
371        Ok(Self {
372            flags: u8::decode(src)?,
373        })
374    }
375}
376
377#[derive(Debug, Clone, PartialEq)]
378pub struct ServerboundPlayerAction {
379    pub status: VarInt,
380
381    pub location: i64,
382
383    pub face: i8,
384
385    pub sequence: VarInt,
386}
387
388impl PacketId for ServerboundPlayerAction {
389    fn packet_id(_ver: u32) -> u8 {
390        0x24
391    }
392}
393
394impl Encode for ServerboundPlayerAction {
395    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
396        self.status.encode(dst)?;
397        self.location.encode(dst)?;
398        self.face.encode(dst)?;
399        self.sequence.encode(dst)
400    }
401}
402
403impl Decode for ServerboundPlayerAction {
404    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
405        Ok(Self {
406            status: VarInt::decode(src)?,
407            location: i64::decode(src)?,
408            face: i8::decode(src)?,
409            sequence: VarInt::decode(src)?,
410        })
411    }
412}
413
414#[derive(Debug, Clone, PartialEq)]
415pub struct ServerboundSetCarriedItem {
416    pub slot: i16,
417}
418
419impl PacketId for ServerboundSetCarriedItem {
420    fn packet_id(_ver: u32) -> u8 {
421        0x2C
422    }
423}
424
425impl Encode for ServerboundSetCarriedItem {
426    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
427        self.slot.encode(dst)
428    }
429}
430
431impl Decode for ServerboundSetCarriedItem {
432    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
433        Ok(Self {
434            slot: i16::decode(src)?,
435        })
436    }
437}
438
439#[derive(Debug, Clone, PartialEq)]
440pub struct ServerboundSwingArm {
441    pub hand: VarInt,
442}
443
444impl PacketId for ServerboundSwingArm {
445    fn packet_id(_ver: u32) -> u8 {
446        0x33
447    }
448}
449
450impl Encode for ServerboundSwingArm {
451    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
452        self.hand.encode(dst)
453    }
454}
455
456impl Decode for ServerboundSwingArm {
457    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
458        Ok(Self {
459            hand: VarInt::decode(src)?,
460        })
461    }
462}
463
464#[derive(Debug, Clone, PartialEq)]
465pub struct ServerboundUseItemOn {
466    pub hand: VarInt,
467
468    pub location: i64,
469
470    pub face: VarInt,
471
472    pub cursor_x: f32,
473
474    pub cursor_y: f32,
475
476    pub cursor_z: f32,
477
478    pub inside_block: bool,
479
480    pub sequence: VarInt,
481}
482
483impl PacketId for ServerboundUseItemOn {
484    fn packet_id(_ver: u32) -> u8 {
485        0x36
486    }
487}
488
489impl Encode for ServerboundUseItemOn {
490    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
491        self.hand.encode(dst)?;
492        self.location.encode(dst)?;
493        self.face.encode(dst)?;
494        self.cursor_x.encode(dst)?;
495        self.cursor_y.encode(dst)?;
496        self.cursor_z.encode(dst)?;
497        self.inside_block.encode(dst)?;
498        self.sequence.encode(dst)
499    }
500}
501
502impl Decode for ServerboundUseItemOn {
503    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
504        Ok(Self {
505            hand: VarInt::decode(src)?,
506            location: i64::decode(src)?,
507            face: VarInt::decode(src)?,
508            cursor_x: f32::decode(src)?,
509            cursor_y: f32::decode(src)?,
510            cursor_z: f32::decode(src)?,
511            inside_block: bool::decode(src)?,
512            sequence: VarInt::decode(src)?,
513        })
514    }
515}
516
517#[derive(Debug, Clone, PartialEq)]
518pub struct ServerboundUseItem {
519    pub hand: VarInt,
520
521    pub sequence: VarInt,
522}
523
524impl PacketId for ServerboundUseItem {
525    fn packet_id(_ver: u32) -> u8 {
526        0x37
527    }
528}
529
530impl Encode for ServerboundUseItem {
531    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
532        self.hand.encode(dst)?;
533        self.sequence.encode(dst)
534    }
535}
536
537impl Decode for ServerboundUseItem {
538    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
539        Ok(Self {
540            hand: VarInt::decode(src)?,
541            sequence: VarInt::decode(src)?,
542        })
543    }
544}
545
546#[derive(Debug, Clone, PartialEq)]
547pub struct ClientboundBundleDelimiter;
548
549impl PacketId for ClientboundBundleDelimiter {
550    fn packet_id(_ver: u32) -> u8 {
551        0x00
552    }
553}
554
555impl Encode for ClientboundBundleDelimiter {
556    fn encode(&self, _dst: &mut BytesMut) -> Result<(), ProtocolError> {
557        Ok(())
558    }
559}
560
561impl Decode for ClientboundBundleDelimiter {
562    fn decode(_src: &mut Bytes) -> Result<Self, ProtocolError> {
563        Ok(Self)
564    }
565}
566
567#[derive(Debug, Clone, PartialEq)]
568pub enum BossBarAction {
569    Add {
570        title: String,
571        health: f32,
572        color: VarInt,
573        division: VarInt,
574        flags: u8,
575    },
576    Remove,
577    UpdateHealth {
578        health: f32,
579    },
580    UpdateTitle {
581        title: String,
582    },
583    UpdateStyle {
584        color: VarInt,
585        division: VarInt,
586    },
587    UpdateFlags {
588        flags: u8,
589    },
590}
591
592#[derive(Debug, Clone, PartialEq)]
593pub struct ClientboundBossBar {
594    pub uuid: uuid::Uuid,
595    pub action: BossBarAction,
596}
597
598impl PacketId for ClientboundBossBar {
599    fn packet_id(_ver: u32) -> u8 {
600        0x0A
601    }
602}
603
604impl Encode for ClientboundBossBar {
605    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
606        self.uuid.encode(dst)?;
607        match &self.action {
608            BossBarAction::Add {
609                title,
610                health,
611                color,
612                division,
613                flags,
614            } => {
615                VarInt(0).encode(dst)?;
616                title.encode(dst)?;
617                health.encode(dst)?;
618                color.encode(dst)?;
619                division.encode(dst)?;
620                flags.encode(dst)?;
621            },
622            BossBarAction::Remove => VarInt(1).encode(dst)?,
623            BossBarAction::UpdateHealth { health } => {
624                VarInt(2).encode(dst)?;
625                health.encode(dst)?;
626            },
627            BossBarAction::UpdateTitle { title } => {
628                VarInt(3).encode(dst)?;
629                title.encode(dst)?;
630            },
631            BossBarAction::UpdateStyle { color, division } => {
632                VarInt(4).encode(dst)?;
633                color.encode(dst)?;
634                division.encode(dst)?;
635            },
636            BossBarAction::UpdateFlags { flags } => {
637                VarInt(5).encode(dst)?;
638                flags.encode(dst)?;
639            },
640        }
641        Ok(())
642    }
643}
644
645impl Decode for ClientboundBossBar {
646    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
647        let uuid = uuid::Uuid::decode(src)?;
648        let action = match VarInt::decode(src)?.0 {
649            0 => BossBarAction::Add {
650                title: String::decode(src)?,
651                health: f32::decode(src)?,
652                color: VarInt::decode(src)?,
653                division: VarInt::decode(src)?,
654                flags: u8::decode(src)?,
655            },
656            1 => BossBarAction::Remove,
657            2 => BossBarAction::UpdateHealth {
658                health: f32::decode(src)?,
659            },
660            3 => BossBarAction::UpdateTitle {
661                title: String::decode(src)?,
662            },
663            4 => BossBarAction::UpdateStyle {
664                color: VarInt::decode(src)?,
665                division: VarInt::decode(src)?,
666            },
667            5 => BossBarAction::UpdateFlags {
668                flags: u8::decode(src)?,
669            },
670            _ => return Err(ProtocolError::UnexpectedEof),
671        };
672        Ok(Self { uuid, action })
673    }
674}
675
676#[derive(Debug, Clone, PartialEq)]
677pub struct ClientboundDisconnect {
678    pub reason: String,
679}
680
681impl PacketId for ClientboundDisconnect {
682    fn packet_id(_ver: u32) -> u8 {
683        0x1A
684    }
685}
686
687impl Encode for ClientboundDisconnect {
688    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
689        self.reason.encode(dst)
690    }
691}
692
693impl Decode for ClientboundDisconnect {
694    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
695        Ok(Self {
696            reason: String::decode(src)?,
697        })
698    }
699}
700
701#[derive(Debug, Clone, PartialEq)]
702pub struct ClientboundEntityEvent {
703    pub entity_id: i32,
704
705    pub event_id: i8,
706}
707
708impl PacketId for ClientboundEntityEvent {
709    fn packet_id(_ver: u32) -> u8 {
710        0x1C
711    }
712}
713
714impl Encode for ClientboundEntityEvent {
715    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
716        self.entity_id.encode(dst)?;
717        self.event_id.encode(dst)
718    }
719}
720
721impl Decode for ClientboundEntityEvent {
722    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
723        Ok(Self {
724            entity_id: i32::decode(src)?,
725            event_id: i8::decode(src)?,
726        })
727    }
728}
729
730#[derive(Debug, Clone, PartialEq)]
731pub struct ClientboundGameEvent {
732    pub event: u8,
733
734    pub value: f32,
735}
736
737impl PacketId for ClientboundGameEvent {
738    fn packet_id(_ver: u32) -> u8 {
739        0x1E
740    }
741}
742
743impl Encode for ClientboundGameEvent {
744    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
745        self.event.encode(dst)?;
746        self.value.encode(dst)
747    }
748}
749
750impl Decode for ClientboundGameEvent {
751    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
752        Ok(Self {
753            event: u8::decode(src)?,
754            value: f32::decode(src)?,
755        })
756    }
757}
758
759#[derive(Debug, Clone, PartialEq)]
760pub struct ClientboundKeepAlive {
761    pub id: i64,
762}
763
764impl PacketId for ClientboundKeepAlive {
765    fn packet_id(_ver: u32) -> u8 {
766        0x24
767    }
768}
769
770impl Encode for ClientboundKeepAlive {
771    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
772        self.id.encode(dst)
773    }
774}
775
776impl Decode for ClientboundKeepAlive {
777    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
778        Ok(Self {
779            id: i64::decode(src)?,
780        })
781    }
782}
783
784#[derive(Debug, Clone, PartialEq)]
785pub struct ClientboundLogin {
786    pub entity_id: i32,
787    pub is_hardcore: bool,
788
789    pub dimension_names: Vec<String>,
790    pub max_players: VarInt,
791    pub view_distance: VarInt,
792    pub simulation_distance: VarInt,
793    pub reduced_debug_info: bool,
794    pub enable_respawn_screen: bool,
795    pub do_limited_crafting: bool,
796
797    pub dimension_type: VarInt,
798    pub dimension_name: String,
799    pub hashed_seed: i64,
800    pub game_mode: u8,
801
802    pub previous_game_mode: i8,
803    pub is_debug: bool,
804    pub is_flat: bool,
805
806    pub death_location: Option<(String, i64)>,
807    pub portal_cooldown: VarInt,
808}
809
810impl PacketId for ClientboundLogin {
811    fn packet_id(_ver: u32) -> u8 {
812        0x29
813    }
814}
815
816impl Encode for ClientboundLogin {
817    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
818        self.entity_id.encode(dst)?;
819        self.is_hardcore.encode(dst)?;
820        self.dimension_names.encode(dst)?;
821        self.max_players.encode(dst)?;
822        self.view_distance.encode(dst)?;
823        self.simulation_distance.encode(dst)?;
824        self.reduced_debug_info.encode(dst)?;
825        self.enable_respawn_screen.encode(dst)?;
826        self.do_limited_crafting.encode(dst)?;
827        self.dimension_type.encode(dst)?;
828        self.dimension_name.encode(dst)?;
829        self.hashed_seed.encode(dst)?;
830        self.game_mode.encode(dst)?;
831        self.previous_game_mode.encode(dst)?;
832        self.is_debug.encode(dst)?;
833        self.is_flat.encode(dst)?;
834        match &self.death_location {
835            Some((dim, pos)) => {
836                true.encode(dst)?;
837                dim.encode(dst)?;
838                pos.encode(dst)?;
839            },
840            None => false.encode(dst)?,
841        }
842        self.portal_cooldown.encode(dst)
843    }
844}
845
846impl Decode for ClientboundLogin {
847    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
848        let entity_id = i32::decode(src)?;
849        let is_hardcore = bool::decode(src)?;
850        let dimension_names = Vec::<String>::decode(src)?;
851        let max_players = VarInt::decode(src)?;
852        let view_distance = VarInt::decode(src)?;
853        let simulation_distance = VarInt::decode(src)?;
854        let reduced_debug_info = bool::decode(src)?;
855        let enable_respawn_screen = bool::decode(src)?;
856        let do_limited_crafting = bool::decode(src)?;
857        let dimension_type = VarInt::decode(src)?;
858        let dimension_name = String::decode(src)?;
859        let hashed_seed = i64::decode(src)?;
860        let game_mode = u8::decode(src)?;
861        let previous_game_mode = i8::decode(src)?;
862        let is_debug = bool::decode(src)?;
863        let is_flat = bool::decode(src)?;
864        let death_location = if bool::decode(src)? {
865            Some((String::decode(src)?, i64::decode(src)?))
866        } else {
867            None
868        };
869        let portal_cooldown = VarInt::decode(src)?;
870        Ok(Self {
871            entity_id,
872            is_hardcore,
873            dimension_names,
874            max_players,
875            view_distance,
876            simulation_distance,
877            reduced_debug_info,
878            enable_respawn_screen,
879            do_limited_crafting,
880            dimension_type,
881            dimension_name,
882            hashed_seed,
883            game_mode,
884            previous_game_mode,
885            is_debug,
886            is_flat,
887            death_location,
888            portal_cooldown,
889        })
890    }
891}
892
893#[derive(Debug, Clone, PartialEq)]
894pub struct ClientboundPluginMessage {
895    pub channel: String,
896    pub data: Vec<u8>,
897}
898
899impl PacketId for ClientboundPluginMessage {
900    fn packet_id(_ver: u32) -> u8 {
901        0x17
902    }
903}
904
905impl Encode for ClientboundPluginMessage {
906    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
907        self.channel.encode(dst)?;
908        dst.extend_from_slice(&self.data);
909        Ok(())
910    }
911}
912
913impl Decode for ClientboundPluginMessage {
914    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
915        let channel = String::decode(src)?;
916        let data = src.copy_to_bytes(src.remaining()).to_vec();
917        Ok(Self { channel, data })
918    }
919}
920
921#[derive(Debug, Clone, PartialEq)]
922pub struct ClientboundPlayerPosition {
923    pub x: f64,
924    pub y: f64,
925    pub z: f64,
926    pub yaw: f32,
927    pub pitch: f32,
928
929    pub flags: u8,
930
931    pub teleport_id: VarInt,
932}
933
934impl PacketId for ClientboundPlayerPosition {
935    fn packet_id(_ver: u32) -> u8 {
936        0x3E
937    }
938}
939
940impl Encode for ClientboundPlayerPosition {
941    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
942        self.x.encode(dst)?;
943        self.y.encode(dst)?;
944        self.z.encode(dst)?;
945        self.yaw.encode(dst)?;
946        self.pitch.encode(dst)?;
947        self.flags.encode(dst)?;
948        self.teleport_id.encode(dst)
949    }
950}
951
952impl Decode for ClientboundPlayerPosition {
953    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
954        Ok(Self {
955            x: f64::decode(src)?,
956            y: f64::decode(src)?,
957            z: f64::decode(src)?,
958            yaw: f32::decode(src)?,
959            pitch: f32::decode(src)?,
960            flags: u8::decode(src)?,
961            teleport_id: VarInt::decode(src)?,
962        })
963    }
964}
965
966#[derive(Debug, Clone, PartialEq)]
967pub struct ClientboundRespawn {
968    pub dimension_type: VarInt,
969    pub dimension_name: String,
970    pub hashed_seed: i64,
971    pub game_mode: u8,
972    pub previous_game_mode: i8,
973    pub is_debug: bool,
974    pub is_flat: bool,
975
976    pub data_kept: u8,
977    pub death_location: Option<(String, i64)>,
978    pub portal_cooldown: VarInt,
979}
980
981impl PacketId for ClientboundRespawn {
982    fn packet_id(_ver: u32) -> u8 {
983        0x43
984    }
985}
986
987impl Encode for ClientboundRespawn {
988    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
989        self.dimension_type.encode(dst)?;
990        self.dimension_name.encode(dst)?;
991        self.hashed_seed.encode(dst)?;
992        self.game_mode.encode(dst)?;
993        self.previous_game_mode.encode(dst)?;
994        self.is_debug.encode(dst)?;
995        self.is_flat.encode(dst)?;
996        self.data_kept.encode(dst)?;
997        match &self.death_location {
998            Some((dim, pos)) => {
999                true.encode(dst)?;
1000                dim.encode(dst)?;
1001                pos.encode(dst)?;
1002            },
1003            None => false.encode(dst)?,
1004        }
1005        self.portal_cooldown.encode(dst)
1006    }
1007}
1008
1009impl Decode for ClientboundRespawn {
1010    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1011        let dimension_type = VarInt::decode(src)?;
1012        let dimension_name = String::decode(src)?;
1013        let hashed_seed = i64::decode(src)?;
1014        let game_mode = u8::decode(src)?;
1015        let previous_game_mode = i8::decode(src)?;
1016        let is_debug = bool::decode(src)?;
1017        let is_flat = bool::decode(src)?;
1018        let data_kept = u8::decode(src)?;
1019        let death_location = if bool::decode(src)? {
1020            Some((String::decode(src)?, i64::decode(src)?))
1021        } else {
1022            None
1023        };
1024        let portal_cooldown = VarInt::decode(src)?;
1025        Ok(Self {
1026            dimension_type,
1027            dimension_name,
1028            hashed_seed,
1029            game_mode,
1030            previous_game_mode,
1031            is_debug,
1032            is_flat,
1033            data_kept,
1034            death_location,
1035            portal_cooldown,
1036        })
1037    }
1038}
1039
1040#[derive(Debug, Clone, PartialEq)]
1041pub struct ClientboundPlayerAbilities {
1042    pub flags: u8,
1043    pub flying_speed: f32,
1044
1045    pub walking_speed: f32,
1046}
1047
1048impl PacketId for ClientboundPlayerAbilities {
1049    fn packet_id(_ver: u32) -> u8 {
1050        0x40
1051    }
1052}
1053
1054impl Encode for ClientboundPlayerAbilities {
1055    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1056        self.flags.encode(dst)?;
1057        self.flying_speed.encode(dst)?;
1058        self.walking_speed.encode(dst)
1059    }
1060}
1061
1062impl Decode for ClientboundPlayerAbilities {
1063    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1064        Ok(Self {
1065            flags: u8::decode(src)?,
1066            flying_speed: f32::decode(src)?,
1067            walking_speed: f32::decode(src)?,
1068        })
1069    }
1070}
1071
1072#[derive(Debug, Clone, PartialEq)]
1073pub struct ClientboundSetCarriedItem {
1074    pub slot: i8,
1075}
1076
1077impl PacketId for ClientboundSetCarriedItem {
1078    fn packet_id(_ver: u32) -> u8 {
1079        0x53
1080    }
1081}
1082
1083impl Encode for ClientboundSetCarriedItem {
1084    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1085        self.slot.encode(dst)
1086    }
1087}
1088
1089impl Decode for ClientboundSetCarriedItem {
1090    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1091        Ok(Self {
1092            slot: i8::decode(src)?,
1093        })
1094    }
1095}
1096
1097#[derive(Debug, Clone, PartialEq)]
1098pub struct ClientboundSetDefaultSpawnPosition {
1099    pub location: i64,
1100    pub angle: f32,
1101}
1102
1103impl PacketId for ClientboundSetDefaultSpawnPosition {
1104    fn packet_id(_ver: u32) -> u8 {
1105        0x54
1106    }
1107}
1108
1109impl Encode for ClientboundSetDefaultSpawnPosition {
1110    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1111        self.location.encode(dst)?;
1112        self.angle.encode(dst)
1113    }
1114}
1115
1116impl Decode for ClientboundSetDefaultSpawnPosition {
1117    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1118        Ok(Self {
1119            location: i64::decode(src)?,
1120            angle: f32::decode(src)?,
1121        })
1122    }
1123}
1124
1125#[derive(Debug, Clone, PartialEq)]
1126pub struct ClientboundSetTime {
1127    pub world_age: i64,
1128
1129    pub time_of_day: i64,
1130}
1131
1132impl PacketId for ClientboundSetTime {
1133    fn packet_id(_ver: u32) -> u8 {
1134        0x62
1135    }
1136}
1137
1138impl Encode for ClientboundSetTime {
1139    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1140        self.world_age.encode(dst)?;
1141        self.time_of_day.encode(dst)
1142    }
1143}
1144
1145impl Decode for ClientboundSetTime {
1146    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1147        Ok(Self {
1148            world_age: i64::decode(src)?,
1149            time_of_day: i64::decode(src)?,
1150        })
1151    }
1152}
1153
1154#[derive(Debug, Clone, PartialEq)]
1155pub struct ClientboundSystemChat {
1156    pub content: String,
1157
1158    pub overlay: bool,
1159}
1160
1161impl PacketId for ClientboundSystemChat {
1162    fn packet_id(_ver: u32) -> u8 {
1163        0x6C
1164    }
1165}
1166
1167impl Encode for ClientboundSystemChat {
1168    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1169        self.content.encode(dst)?;
1170        self.overlay.encode(dst)
1171    }
1172}
1173
1174impl Decode for ClientboundSystemChat {
1175    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1176        Ok(Self {
1177            content: String::decode(src)?,
1178            overlay: bool::decode(src)?,
1179        })
1180    }
1181}
1182
1183#[cfg(test)]
1184mod tests {
1185    use super::*;
1186
1187    #[test]
1188    fn accept_teleportation_roundtrip() {
1189        let p = ServerboundAcceptTeleportation {
1190            teleport_id: VarInt(7),
1191        };
1192        let mut buf = BytesMut::new();
1193        p.encode(&mut buf).unwrap();
1194        assert_eq!(
1195            ServerboundAcceptTeleportation::decode(&mut buf.freeze()).unwrap(),
1196            p
1197        );
1198    }
1199
1200    #[test]
1201    fn client_information_roundtrip() {
1202        let p = ServerboundClientInformation {
1203            locale: "en_US".to_string(),
1204            view_distance: 12,
1205            chat_mode: VarInt(0),
1206            chat_colors: true,
1207            displayed_skin_parts: 0x7F,
1208            main_hand: VarInt(1),
1209            enable_text_filtering: false,
1210            allow_server_listings: true,
1211        };
1212        let mut buf = BytesMut::new();
1213        p.encode(&mut buf).unwrap();
1214        assert_eq!(
1215            ServerboundClientInformation::decode(&mut buf.freeze()).unwrap(),
1216            p
1217        );
1218    }
1219
1220    #[test]
1221    fn keep_alive_roundtrip() {
1222        let p = ClientboundKeepAlive { id: 987654321 };
1223        let mut buf = BytesMut::new();
1224        p.encode(&mut buf).unwrap();
1225        assert_eq!(ClientboundKeepAlive::decode(&mut buf.freeze()).unwrap(), p);
1226
1227        let p2 = ServerboundKeepAlive { id: 987654321 };
1228        let mut buf2 = BytesMut::new();
1229        p2.encode(&mut buf2).unwrap();
1230        assert_eq!(
1231            ServerboundKeepAlive::decode(&mut buf2.freeze()).unwrap(),
1232            p2
1233        );
1234    }
1235
1236    #[test]
1237    fn move_pos_roundtrip() {
1238        let p = ServerboundMovePlayerPos {
1239            x: 3.5,
1240            feet_y: 64.0,
1241            z: 2.71,
1242            on_ground: true,
1243        };
1244        let mut buf = BytesMut::new();
1245        p.encode(&mut buf).unwrap();
1246        assert_eq!(
1247            ServerboundMovePlayerPos::decode(&mut buf.freeze()).unwrap(),
1248            p
1249        );
1250    }
1251
1252    #[test]
1253    fn move_pos_rot_roundtrip() {
1254        let p = ServerboundMovePlayerPosRot {
1255            x: 1.0,
1256            feet_y: 65.0,
1257            z: -1.0,
1258            yaw: 45.0,
1259            pitch: -10.0,
1260            on_ground: false,
1261        };
1262        let mut buf = BytesMut::new();
1263        p.encode(&mut buf).unwrap();
1264        assert_eq!(
1265            ServerboundMovePlayerPosRot::decode(&mut buf.freeze()).unwrap(),
1266            p
1267        );
1268    }
1269
1270    #[test]
1271    fn move_rot_roundtrip() {
1272        let p = ServerboundMovePlayerRot {
1273            yaw: 90.0,
1274            pitch: 0.0,
1275            on_ground: true,
1276        };
1277        let mut buf = BytesMut::new();
1278        p.encode(&mut buf).unwrap();
1279        assert_eq!(
1280            ServerboundMovePlayerRot::decode(&mut buf.freeze()).unwrap(),
1281            p
1282        );
1283    }
1284
1285    #[test]
1286    fn move_status_only_roundtrip() {
1287        let p = ServerboundMovePlayerStatusOnly { on_ground: false };
1288        let mut buf = BytesMut::new();
1289        p.encode(&mut buf).unwrap();
1290        assert_eq!(
1291            ServerboundMovePlayerStatusOnly::decode(&mut buf.freeze()).unwrap(),
1292            p
1293        );
1294    }
1295
1296    #[test]
1297    fn interact_interact_at_roundtrip() {
1298        let p = ServerboundInteract {
1299            entity_id: VarInt(12),
1300            action: InteractAction::InteractAt {
1301                target_x: 0.5,
1302                target_y: 0.5,
1303                target_z: 0.5,
1304                hand: VarInt(1),
1305            },
1306            sneaking: true,
1307        };
1308        let mut buf = BytesMut::new();
1309        p.encode(&mut buf).unwrap();
1310        assert_eq!(ServerboundInteract::decode(&mut buf.freeze()).unwrap(), p);
1311    }
1312
1313    #[test]
1314    fn player_position_roundtrip() {
1315        let p = ClientboundPlayerPosition {
1316            x: 0.0,
1317            y: 64.0,
1318            z: 0.0,
1319            yaw: 90.0,
1320            pitch: 5.0,
1321            flags: 0x1F,
1322            teleport_id: VarInt(2),
1323        };
1324        let mut buf = BytesMut::new();
1325        p.encode(&mut buf).unwrap();
1326        assert_eq!(
1327            ClientboundPlayerPosition::decode(&mut buf.freeze()).unwrap(),
1328            p
1329        );
1330    }
1331
1332    #[test]
1333    fn plugin_message_roundtrip() {
1334        let p = ClientboundPluginMessage {
1335            channel: "minecraft:brand".to_string(),
1336            data: b"purpur".to_vec(),
1337        };
1338        let mut buf = BytesMut::new();
1339        p.encode(&mut buf).unwrap();
1340        assert_eq!(
1341            ClientboundPluginMessage::decode(&mut buf.freeze()).unwrap(),
1342            p
1343        );
1344    }
1345
1346    #[test]
1347    fn disconnect_roundtrip() {
1348        let p = ClientboundDisconnect {
1349            reason: r#"{"text":"server closing"}"#.to_string(),
1350        };
1351        let mut buf = BytesMut::new();
1352        p.encode(&mut buf).unwrap();
1353        assert_eq!(ClientboundDisconnect::decode(&mut buf.freeze()).unwrap(), p);
1354    }
1355
1356    #[test]
1357    fn game_event_roundtrip() {
1358        let p = ClientboundGameEvent {
1359            event: 3,
1360            value: 1.0,
1361        };
1362        let mut buf = BytesMut::new();
1363        p.encode(&mut buf).unwrap();
1364        assert_eq!(ClientboundGameEvent::decode(&mut buf.freeze()).unwrap(), p);
1365    }
1366
1367    #[test]
1368    fn system_chat_roundtrip() {
1369        let p = ClientboundSystemChat {
1370            content: r#"{"text":"Hello!"}"#.to_string(),
1371            overlay: false,
1372        };
1373        let mut buf = BytesMut::new();
1374        p.encode(&mut buf).unwrap();
1375        assert_eq!(ClientboundSystemChat::decode(&mut buf.freeze()).unwrap(), p);
1376    }
1377
1378    #[test]
1379    fn set_time_roundtrip() {
1380        let p = ClientboundSetTime {
1381            world_age: 24000,
1382            time_of_day: 6000,
1383        };
1384        let mut buf = BytesMut::new();
1385        p.encode(&mut buf).unwrap();
1386        assert_eq!(ClientboundSetTime::decode(&mut buf.freeze()).unwrap(), p);
1387    }
1388
1389    #[test]
1390    fn respawn_roundtrip() {
1391        let p = ClientboundRespawn {
1392            dimension_type: VarInt(0),
1393            dimension_name: "minecraft:overworld".to_string(),
1394            hashed_seed: 0,
1395            game_mode: 0,
1396            previous_game_mode: -1,
1397            is_debug: false,
1398            is_flat: false,
1399            data_kept: 0x01,
1400            death_location: None,
1401            portal_cooldown: VarInt(0),
1402        };
1403        let mut buf = BytesMut::new();
1404        p.encode(&mut buf).unwrap();
1405        assert_eq!(ClientboundRespawn::decode(&mut buf.freeze()).unwrap(), p);
1406    }
1407
1408    #[test]
1409    fn boss_bar_add_roundtrip() {
1410        let p = ClientboundBossBar {
1411            uuid: uuid::Uuid::new_v4(),
1412            action: BossBarAction::Add {
1413                title: r#"{"text":"Boss"}"#.to_string(),
1414                health: 0.75,
1415                color: VarInt(1),
1416                division: VarInt(0),
1417                flags: 0,
1418            },
1419        };
1420        let mut buf = BytesMut::new();
1421        p.encode(&mut buf).unwrap();
1422        assert_eq!(ClientboundBossBar::decode(&mut buf.freeze()).unwrap(), p);
1423    }
1424
1425    #[test]
1426    fn packet_ids() {
1427        assert_eq!(ServerboundAcceptTeleportation::packet_id(765), 0x05);
1428        assert_eq!(ServerboundClientInformation::packet_id(765), 0x09);
1429        assert_eq!(ServerboundInteract::packet_id(765), 0x13);
1430        assert_eq!(ServerboundKeepAlive::packet_id(765), 0x18);
1431        assert_eq!(ServerboundMovePlayerStatusOnly::packet_id(765), 0x14);
1432        assert_eq!(ServerboundMovePlayerPos::packet_id(765), 0x15);
1433        assert_eq!(ServerboundMovePlayerRot::packet_id(765), 0x16);
1434        assert_eq!(ServerboundMovePlayerPosRot::packet_id(765), 0x17);
1435        assert_eq!(ServerboundPluginMessage::packet_id(765), 0x0F);
1436        assert_eq!(ServerboundPlayerAbilities::packet_id(765), 0x22);
1437        assert_eq!(ServerboundPlayerAction::packet_id(765), 0x24);
1438        assert_eq!(ServerboundSetCarriedItem::packet_id(765), 0x2C);
1439        assert_eq!(ServerboundSwingArm::packet_id(765), 0x33);
1440        assert_eq!(ServerboundUseItemOn::packet_id(765), 0x36);
1441        assert_eq!(ServerboundUseItem::packet_id(765), 0x37);
1442        assert_eq!(ClientboundBundleDelimiter::packet_id(765), 0x00);
1443        assert_eq!(ClientboundBossBar::packet_id(765), 0x0A);
1444        assert_eq!(ClientboundDisconnect::packet_id(765), 0x1A);
1445        assert_eq!(ClientboundEntityEvent::packet_id(765), 0x1C);
1446        assert_eq!(ClientboundGameEvent::packet_id(765), 0x1E);
1447        assert_eq!(ClientboundKeepAlive::packet_id(765), 0x24);
1448        assert_eq!(ClientboundLogin::packet_id(765), 0x29);
1449        assert_eq!(ClientboundPluginMessage::packet_id(765), 0x17);
1450        assert_eq!(ClientboundPlayerPosition::packet_id(765), 0x3E);
1451        assert_eq!(ClientboundRespawn::packet_id(765), 0x43);
1452        assert_eq!(ClientboundPlayerAbilities::packet_id(765), 0x40);
1453        assert_eq!(ClientboundSetCarriedItem::packet_id(765), 0x53);
1454        assert_eq!(ClientboundSetDefaultSpawnPosition::packet_id(765), 0x54);
1455        assert_eq!(ClientboundSetTime::packet_id(765), 0x62);
1456        assert_eq!(ClientboundSystemChat::packet_id(765), 0x6C);
1457    }
1458}