Skip to main content

kojacoord_protocol/versions/v1_6_4/play/
mod.rs

1use bytes::{Buf, BufMut, Bytes, BytesMut};
2
3use crate::codec::{Decode, Encode, PacketId};
4use crate::error::ProtocolError;
5
6fn decode_legacy_string(src: &mut Bytes) -> Result<String, ProtocolError> {
7    if src.len() < 2 {
8        return Err(ProtocolError::UnexpectedEof);
9    }
10    let len = u16::from_be_bytes([src[0], src[1]]) as usize;
11    src.advance(2);
12    let byte_len = len * 2;
13    if src.len() < byte_len {
14        return Err(ProtocolError::UnexpectedEof);
15    }
16    let raw = src.copy_to_bytes(byte_len);
17    let chars: Vec<u16> = raw
18        .chunks(2)
19        .map(|c| u16::from_be_bytes([c[0], c[1]]))
20        .collect();
21    String::from_utf16(&chars).map_err(|_| ProtocolError::UnexpectedEof)
22}
23
24fn encode_legacy_string(s: &str, dst: &mut BytesMut) {
25    let utf16: Vec<u16> = s.encode_utf16().collect();
26    dst.extend_from_slice(&(utf16.len() as u16).to_be_bytes());
27    for ch in &utf16 {
28        dst.extend_from_slice(&ch.to_be_bytes());
29    }
30}
31
32fn need(src: &Bytes, n: usize) -> Result<(), ProtocolError> {
33    if src.remaining() < n {
34        Err(ProtocolError::UnexpectedEof)
35    } else {
36        Ok(())
37    }
38}
39
40#[derive(Debug, Clone, PartialEq)]
41pub struct ClientboundKeepAlive {
42    pub keep_alive_id: i32,
43}
44
45impl PacketId for ClientboundKeepAlive {
46    fn packet_id(_ver: u32) -> u8 {
47        0x00
48    }
49}
50
51impl Encode for ClientboundKeepAlive {
52    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
53        dst.extend_from_slice(&self.keep_alive_id.to_be_bytes());
54        Ok(())
55    }
56}
57
58impl Decode for ClientboundKeepAlive {
59    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
60        need(src, 4)?;
61        Ok(Self {
62            keep_alive_id: src.get_i32(),
63        })
64    }
65}
66
67#[derive(Debug, Clone, PartialEq)]
68pub struct ClientboundChatMessage {
69    pub message: String,
70}
71
72impl PacketId for ClientboundChatMessage {
73    fn packet_id(_ver: u32) -> u8 {
74        0x03
75    }
76}
77
78impl Encode for ClientboundChatMessage {
79    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
80        encode_legacy_string(&self.message, dst);
81        Ok(())
82    }
83}
84
85impl Decode for ClientboundChatMessage {
86    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
87        Ok(Self {
88            message: decode_legacy_string(src)?,
89        })
90    }
91}
92
93#[derive(Debug, Clone, PartialEq)]
94pub struct ClientboundPlayerPosition {
95    pub x: f64,
96    pub y: f64,
97    pub stance: f64,
98    pub z: f64,
99    pub yaw: f32,
100    pub pitch: f32,
101    pub on_ground: bool,
102}
103
104impl PacketId for ClientboundPlayerPosition {
105    fn packet_id(_ver: u32) -> u8 {
106        0x13
107    }
108}
109
110impl Encode for ClientboundPlayerPosition {
111    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
112        dst.put_f64(self.x);
113        dst.put_f64(self.y);
114        dst.put_f64(self.stance);
115        dst.put_f64(self.z);
116        dst.put_f32(self.yaw);
117        dst.put_f32(self.pitch);
118        dst.put_u8(self.on_ground as u8);
119        Ok(())
120    }
121}
122
123impl Decode for ClientboundPlayerPosition {
124    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
125        need(src, 8 + 8 + 8 + 8 + 4 + 4 + 1)?;
126        Ok(Self {
127            x: src.get_f64(),
128            y: src.get_f64(),
129            stance: src.get_f64(),
130            z: src.get_f64(),
131            yaw: src.get_f32(),
132            pitch: src.get_f32(),
133            on_ground: src.get_u8() != 0,
134        })
135    }
136}
137
138#[derive(Debug, Clone, PartialEq)]
139pub struct ClientboundHeldItemChange {
140    pub slot: i8,
141}
142
143impl PacketId for ClientboundHeldItemChange {
144    fn packet_id(_ver: u32) -> u8 {
145        0x09
146    }
147}
148
149impl Encode for ClientboundHeldItemChange {
150    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
151        dst.put_i8(self.slot);
152        Ok(())
153    }
154}
155
156impl Decode for ClientboundHeldItemChange {
157    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
158        need(src, 1)?;
159        Ok(Self { slot: src.get_i8() })
160    }
161}
162
163#[derive(Debug, Clone, PartialEq)]
164pub struct ClientboundPlayerAbilities {
165    pub flags: u8,
166    pub flying_speed: f32,
167    pub walking_speed: f32,
168}
169
170impl PacketId for ClientboundPlayerAbilities {
171    fn packet_id(_ver: u32) -> u8 {
172        0x43
173    }
174}
175
176impl Encode for ClientboundPlayerAbilities {
177    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
178        dst.put_u8(self.flags);
179        dst.put_f32(self.flying_speed);
180        dst.put_f32(self.walking_speed);
181        Ok(())
182    }
183}
184
185impl Decode for ClientboundPlayerAbilities {
186    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
187        need(src, 1 + 4 + 4)?;
188        Ok(Self {
189            flags: src.get_u8(),
190            flying_speed: src.get_f32(),
191            walking_speed: src.get_f32(),
192        })
193    }
194}
195
196#[derive(Debug, Clone, PartialEq)]
197pub struct ClientboundDisconnect {
198    pub reason: String,
199}
200
201impl PacketId for ClientboundDisconnect {
202    fn packet_id(_ver: u32) -> u8 {
203        0xFF
204    }
205}
206
207impl Encode for ClientboundDisconnect {
208    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
209        encode_legacy_string(&self.reason, dst);
210        Ok(())
211    }
212}
213
214impl Decode for ClientboundDisconnect {
215    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
216        Ok(Self {
217            reason: decode_legacy_string(src)?,
218        })
219    }
220}
221
222#[derive(Debug, Clone, PartialEq)]
223pub struct ClientboundSpawnPosition {
224    pub x: i32,
225    pub y: i32,
226    pub z: i32,
227}
228
229impl PacketId for ClientboundSpawnPosition {
230    fn packet_id(_ver: u32) -> u8 {
231        0x05
232    }
233}
234
235impl Encode for ClientboundSpawnPosition {
236    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
237        dst.put_i32(self.x);
238        dst.put_i32(self.y);
239        dst.put_i32(self.z);
240        Ok(())
241    }
242}
243
244impl Decode for ClientboundSpawnPosition {
245    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
246        need(src, 4 + 4 + 4)?;
247        Ok(Self {
248            x: src.get_i32(),
249            y: src.get_i32(),
250            z: src.get_i32(),
251        })
252    }
253}
254
255#[derive(Debug, Clone, PartialEq)]
256pub struct ClientboundUpdateHealth {
257    pub health: f32,
258    pub food: i16,
259    pub food_saturation: f32,
260}
261
262impl PacketId for ClientboundUpdateHealth {
263    fn packet_id(_ver: u32) -> u8 {
264        0x08
265    }
266}
267
268impl Encode for ClientboundUpdateHealth {
269    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
270        dst.put_f32(self.health);
271        dst.put_i16(self.food);
272        dst.put_f32(self.food_saturation);
273        Ok(())
274    }
275}
276
277impl Decode for ClientboundUpdateHealth {
278    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
279        need(src, 4 + 2 + 4)?;
280        Ok(Self {
281            health: src.get_f32(),
282            food: src.get_i16(),
283            food_saturation: src.get_f32(),
284        })
285    }
286}
287
288#[derive(Debug, Clone, PartialEq)]
289pub struct ClientboundRespawn {
290    pub dimension: i8,
291    pub difficulty: u8,
292    pub gamemode: u8,
293    pub world_height: i16,
294}
295
296impl PacketId for ClientboundRespawn {
297    fn packet_id(_ver: u32) -> u8 {
298        0x09
299    }
300}
301
302impl Encode for ClientboundRespawn {
303    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
304        dst.put_i8(self.dimension);
305        dst.put_u8(self.difficulty);
306        dst.put_u8(self.gamemode);
307        dst.put_i16(self.world_height);
308        Ok(())
309    }
310}
311
312impl Decode for ClientboundRespawn {
313    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
314        need(src, 1 + 1 + 1 + 2)?;
315        Ok(Self {
316            dimension: src.get_i8(),
317            difficulty: src.get_u8(),
318            gamemode: src.get_u8(),
319            world_height: src.get_i16(),
320        })
321    }
322}
323
324#[derive(Debug, Clone, PartialEq)]
325pub struct ClientboundEntityEquipment {
326    pub entity_id: i32,
327    pub slot: i16,
328    pub item_id: i16,
329}
330
331impl PacketId for ClientboundEntityEquipment {
332    fn packet_id(_ver: u32) -> u8 {
333        0x1C
334    }
335}
336
337impl Encode for ClientboundEntityEquipment {
338    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
339        dst.put_i32(self.entity_id);
340        dst.put_i16(self.slot);
341        dst.put_i16(self.item_id);
342        Ok(())
343    }
344}
345
346impl Decode for ClientboundEntityEquipment {
347    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
348        need(src, 4 + 2 + 2)?;
349        Ok(Self {
350            entity_id: src.get_i32(),
351            slot: src.get_i16(),
352            item_id: src.get_i16(),
353        })
354    }
355}
356
357#[derive(Debug, Clone, PartialEq)]
358pub struct ClientboundSpawnPlayer {
359    pub entity_id: i32,
360    pub username: String,
361    pub x: i32,
362    pub y: i32,
363    pub z: i32,
364    pub yaw: i8,
365    pub pitch: i8,
366    pub current_item: i16,
367}
368
369impl PacketId for ClientboundSpawnPlayer {
370    fn packet_id(_ver: u32) -> u8 {
371        0x14
372    }
373}
374
375impl Encode for ClientboundSpawnPlayer {
376    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
377        dst.put_i32(self.entity_id);
378        encode_legacy_string(&self.username, dst);
379        dst.put_i32(self.x);
380        dst.put_i32(self.y);
381        dst.put_i32(self.z);
382        dst.put_i8(self.yaw);
383        dst.put_i8(self.pitch);
384        dst.put_i16(self.current_item);
385        Ok(())
386    }
387}
388
389impl Decode for ClientboundSpawnPlayer {
390    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
391        let entity_id = src.get_i32();
392        let username = decode_legacy_string(src)?;
393        need(src, 4 + 4 + 4 + 1 + 1 + 2)?;
394        Ok(Self {
395            entity_id,
396            username,
397            x: src.get_i32(),
398            y: src.get_i32(),
399            z: src.get_i32(),
400            yaw: src.get_i8(),
401            pitch: src.get_i8(),
402            current_item: src.get_i16(),
403        })
404    }
405}
406
407#[derive(Debug, Clone, PartialEq)]
408pub struct ClientboundChunkData {
409    pub chunk_x: i32,
410    pub chunk_z: i32,
411    pub continuous: bool,
412    pub primary_bitmap: i16,
413    pub add_bitmap: i16,
414    pub compressed_data: Vec<u8>,
415}
416
417impl PacketId for ClientboundChunkData {
418    fn packet_id(_ver: u32) -> u8 {
419        0x33
420    }
421}
422
423impl Encode for ClientboundChunkData {
424    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
425        dst.put_i32(self.chunk_x);
426        dst.put_i32(self.chunk_z);
427        dst.put_u8(self.continuous as u8);
428        dst.put_i16(self.primary_bitmap);
429        dst.put_i16(self.add_bitmap);
430        dst.extend_from_slice(&(self.compressed_data.len() as i32).to_be_bytes());
431        dst.extend_from_slice(&self.compressed_data);
432        Ok(())
433    }
434}
435
436impl Decode for ClientboundChunkData {
437    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
438        need(src, 4 + 4 + 1 + 2 + 2 + 4)?;
439        let chunk_x = src.get_i32();
440        let chunk_z = src.get_i32();
441        let continuous = src.get_u8() != 0;
442        let primary_bitmap = src.get_i16();
443        let add_bitmap = src.get_i16();
444        let data_len = src.get_i32() as usize;
445        if src.remaining() < data_len {
446            return Err(ProtocolError::UnexpectedEof);
447        }
448        let compressed_data = src.copy_to_bytes(data_len).to_vec();
449        Ok(Self {
450            chunk_x,
451            chunk_z,
452            continuous,
453            primary_bitmap,
454            add_bitmap,
455            compressed_data,
456        })
457    }
458}
459
460#[derive(Debug, Clone, PartialEq)]
461pub struct ClientboundMultiBlockChange {
462    pub chunk_x: i32,
463    pub chunk_z: i32,
464    pub record_count: i32,
465    pub data: Vec<u8>,
466}
467
468impl PacketId for ClientboundMultiBlockChange {
469    fn packet_id(_ver: u32) -> u8 {
470        0x34
471    }
472}
473
474impl Encode for ClientboundMultiBlockChange {
475    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
476        dst.put_i32(self.chunk_x);
477        dst.put_i32(self.chunk_z);
478        dst.put_i32(self.record_count);
479        dst.extend_from_slice(&self.data);
480        Ok(())
481    }
482}
483
484impl Decode for ClientboundMultiBlockChange {
485    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
486        need(src, 4 + 4 + 4)?;
487        let chunk_x = src.get_i32();
488        let chunk_z = src.get_i32();
489        let record_count = src.get_i32();
490        let data = src.to_vec();
491        Ok(Self {
492            chunk_x,
493            chunk_z,
494            record_count,
495            data,
496        })
497    }
498}
499
500#[derive(Debug, Clone, PartialEq)]
501pub struct ClientboundBlockChange {
502    pub x: i32,
503    pub y: i8,
504    pub z: i32,
505    pub block_id: i16,
506    pub block_metadata: i8,
507}
508
509impl PacketId for ClientboundBlockChange {
510    fn packet_id(_ver: u32) -> u8 {
511        0x35
512    }
513}
514
515impl Encode for ClientboundBlockChange {
516    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
517        dst.put_i32(self.x);
518        dst.put_i8(self.y);
519        dst.put_i32(self.z);
520        dst.put_i16(self.block_id);
521        dst.put_i8(self.block_metadata);
522        Ok(())
523    }
524}
525
526impl Decode for ClientboundBlockChange {
527    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
528        need(src, 4 + 1 + 4 + 2 + 1)?;
529        Ok(Self {
530            x: src.get_i32(),
531            y: src.get_i8(),
532            z: src.get_i32(),
533            block_id: src.get_i16(),
534            block_metadata: src.get_i8(),
535        })
536    }
537}
538
539#[derive(Debug, Clone, PartialEq)]
540pub struct ClientboundNamedSoundEffect {
541    pub sound_name: String,
542    pub x: i32,
543    pub y: i32,
544    pub z: i32,
545    pub volume: f32,
546    pub pitch: u8,
547}
548
549impl PacketId for ClientboundNamedSoundEffect {
550    fn packet_id(_ver: u32) -> u8 {
551        0x3E
552    }
553}
554
555impl Encode for ClientboundNamedSoundEffect {
556    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
557        encode_legacy_string(&self.sound_name, dst);
558        dst.put_i32(self.x);
559        dst.put_i32(self.y);
560        dst.put_i32(self.z);
561        dst.put_f32(self.volume);
562        dst.put_u8(self.pitch);
563        Ok(())
564    }
565}
566
567impl Decode for ClientboundNamedSoundEffect {
568    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
569        let sound_name = decode_legacy_string(src)?;
570        need(src, 4 + 4 + 4 + 4 + 1)?;
571        Ok(Self {
572            sound_name,
573            x: src.get_i32(),
574            y: src.get_i32(),
575            z: src.get_i32(),
576            volume: src.get_f32(),
577            pitch: src.get_u8(),
578        })
579    }
580}
581
582#[derive(Debug, Clone, PartialEq)]
583pub struct ClientboundSetSlot {
584    pub window_id: i8,
585    pub slot: i16,
586    pub item_id: i16,
587    pub item_count: i8,
588    pub item_damage: i16,
589    pub nbt_data: Vec<u8>,
590}
591
592impl PacketId for ClientboundSetSlot {
593    fn packet_id(_ver: u32) -> u8 {
594        0x67
595    }
596}
597
598impl Encode for ClientboundSetSlot {
599    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
600        dst.put_i8(self.window_id);
601        dst.put_i16(self.slot);
602        dst.put_i16(self.item_id);
603        dst.put_i8(self.item_count);
604        dst.put_i16(self.item_damage);
605        dst.put_i16(self.nbt_data.len() as i16);
606        dst.extend_from_slice(&self.nbt_data);
607        Ok(())
608    }
609}
610
611impl Decode for ClientboundSetSlot {
612    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
613        need(src, 1 + 2 + 2 + 1 + 2 + 2)?;
614        let window_id = src.get_i8();
615        let slot = src.get_i16();
616        let item_id = src.get_i16();
617        let item_count = src.get_i8();
618        let item_damage = src.get_i16();
619        let nbt_len = src.get_i16() as usize;
620        if src.remaining() < nbt_len {
621            return Err(ProtocolError::UnexpectedEof);
622        }
623        let nbt_data = src.copy_to_bytes(nbt_len).to_vec();
624        Ok(Self {
625            window_id,
626            slot,
627            item_id,
628            item_count,
629            item_damage,
630            nbt_data,
631        })
632    }
633}
634
635#[derive(Debug, Clone, PartialEq)]
636pub struct ClientboundWindowItems {
637    pub window_id: i8,
638    pub items: Vec<(i16, i8, i16, Vec<u8>)>,
639}
640
641impl PacketId for ClientboundWindowItems {
642    fn packet_id(_ver: u32) -> u8 {
643        0x68
644    }
645}
646
647impl Encode for ClientboundWindowItems {
648    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
649        dst.put_i8(self.window_id);
650        dst.put_i16(self.items.len() as i16);
651        for (item_id, item_count, item_damage, nbt_data) in &self.items {
652            dst.put_i16(*item_id);
653            dst.put_i8(*item_count);
654            dst.put_i16(*item_damage);
655            dst.put_i16(nbt_data.len() as i16);
656            dst.extend_from_slice(nbt_data);
657        }
658        Ok(())
659    }
660}
661
662impl Decode for ClientboundWindowItems {
663    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
664        need(src, 1 + 2)?;
665        let window_id = src.get_i8();
666        let count = src.get_i16() as usize;
667        let mut items = Vec::with_capacity(count);
668        for _ in 0..count {
669            need(src, 2 + 1 + 2 + 2)?;
670            let item_id = src.get_i16();
671            let item_count = src.get_i8();
672            let item_damage = src.get_i16();
673            let nbt_len = src.get_i16() as usize;
674            if src.remaining() < nbt_len {
675                return Err(ProtocolError::UnexpectedEof);
676            }
677            let nbt_data = src.copy_to_bytes(nbt_len).to_vec();
678            items.push((item_id, item_count, item_damage, nbt_data));
679        }
680        Ok(Self { window_id, items })
681    }
682}
683
684#[derive(Debug, Clone, PartialEq)]
685pub struct ClientboundUpdateTime {
686    pub age: i64,
687    pub time: i64,
688}
689
690impl PacketId for ClientboundUpdateTime {
691    fn packet_id(_ver: u32) -> u8 {
692        0x04
693    }
694}
695
696impl Encode for ClientboundUpdateTime {
697    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
698        dst.put_i64(self.age);
699        dst.put_i64(self.time);
700        Ok(())
701    }
702}
703
704impl Decode for ClientboundUpdateTime {
705    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
706        need(src, 8 + 8)?;
707        Ok(Self {
708            age: src.get_i64(),
709            time: src.get_i64(),
710        })
711    }
712}
713
714#[derive(Debug, Clone, PartialEq)]
715pub struct ClientboundEntity {
716    pub entity_id: i32,
717}
718
719impl PacketId for ClientboundEntity {
720    fn packet_id(_ver: u32) -> u8 {
721        0x1E
722    }
723}
724
725impl Encode for ClientboundEntity {
726    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
727        dst.put_i32(self.entity_id);
728        Ok(())
729    }
730}
731
732impl Decode for ClientboundEntity {
733    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
734        need(src, 4)?;
735        Ok(Self {
736            entity_id: src.get_i32(),
737        })
738    }
739}
740
741#[derive(Debug, Clone, PartialEq)]
742pub struct ClientboundEntityRelativeMove {
743    pub entity_id: i32,
744    pub dx: i8,
745    pub dy: i8,
746    pub dz: i8,
747}
748
749impl PacketId for ClientboundEntityRelativeMove {
750    fn packet_id(_ver: u32) -> u8 {
751        0x15
752    }
753}
754
755impl Encode for ClientboundEntityRelativeMove {
756    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
757        dst.put_i32(self.entity_id);
758        dst.put_i8(self.dx);
759        dst.put_i8(self.dy);
760        dst.put_i8(self.dz);
761        Ok(())
762    }
763}
764
765impl Decode for ClientboundEntityRelativeMove {
766    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
767        need(src, 4 + 1 + 1 + 1)?;
768        Ok(Self {
769            entity_id: src.get_i32(),
770            dx: src.get_i8(),
771            dy: src.get_i8(),
772            dz: src.get_i8(),
773        })
774    }
775}
776
777#[derive(Debug, Clone, PartialEq)]
778pub struct ClientboundEntityLook {
779    pub entity_id: i32,
780    pub yaw: i8,
781    pub pitch: i8,
782}
783
784impl PacketId for ClientboundEntityLook {
785    fn packet_id(_ver: u32) -> u8 {
786        0x16
787    }
788}
789
790impl Encode for ClientboundEntityLook {
791    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
792        dst.put_i32(self.entity_id);
793        dst.put_i8(self.yaw);
794        dst.put_i8(self.pitch);
795        Ok(())
796    }
797}
798
799impl Decode for ClientboundEntityLook {
800    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
801        need(src, 4 + 1 + 1)?;
802        Ok(Self {
803            entity_id: src.get_i32(),
804            yaw: src.get_i8(),
805            pitch: src.get_i8(),
806        })
807    }
808}
809
810#[derive(Debug, Clone, PartialEq)]
811pub struct ClientboundEntityMoveLook {
812    pub entity_id: i32,
813    pub dx: i8,
814    pub dy: i8,
815    pub dz: i8,
816    pub yaw: i8,
817    pub pitch: i8,
818}
819
820impl PacketId for ClientboundEntityMoveLook {
821    fn packet_id(_ver: u32) -> u8 {
822        0x17
823    }
824}
825
826impl Encode for ClientboundEntityMoveLook {
827    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
828        dst.put_i32(self.entity_id);
829        dst.put_i8(self.dx);
830        dst.put_i8(self.dy);
831        dst.put_i8(self.dz);
832        dst.put_i8(self.yaw);
833        dst.put_i8(self.pitch);
834        Ok(())
835    }
836}
837
838impl Decode for ClientboundEntityMoveLook {
839    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
840        need(src, 4 + 1 + 1 + 1 + 1 + 1)?;
841        Ok(Self {
842            entity_id: src.get_i32(),
843            dx: src.get_i8(),
844            dy: src.get_i8(),
845            dz: src.get_i8(),
846            yaw: src.get_i8(),
847            pitch: src.get_i8(),
848        })
849    }
850}
851
852#[derive(Debug, Clone, PartialEq)]
853pub struct ClientboundEntityTeleport {
854    pub entity_id: i32,
855    pub x: i32,
856    pub y: i32,
857    pub z: i32,
858    pub yaw: i8,
859    pub pitch: i8,
860}
861
862impl PacketId for ClientboundEntityTeleport {
863    fn packet_id(_ver: u32) -> u8 {
864        0x18
865    }
866}
867
868impl Encode for ClientboundEntityTeleport {
869    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
870        dst.put_i32(self.entity_id);
871        dst.put_i32(self.x);
872        dst.put_i32(self.y);
873        dst.put_i32(self.z);
874        dst.put_i8(self.yaw);
875        dst.put_i8(self.pitch);
876        Ok(())
877    }
878}
879
880impl Decode for ClientboundEntityTeleport {
881    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
882        need(src, 4 + 4 + 4 + 4 + 1 + 1)?;
883        Ok(Self {
884            entity_id: src.get_i32(),
885            x: src.get_i32(),
886            y: src.get_i32(),
887            z: src.get_i32(),
888            yaw: src.get_i8(),
889            pitch: src.get_i8(),
890        })
891    }
892}
893
894#[derive(Debug, Clone, PartialEq)]
895pub struct ClientboundEntityHeadRotation {
896    pub entity_id: i32,
897    pub head_yaw: i8,
898}
899
900impl PacketId for ClientboundEntityHeadRotation {
901    fn packet_id(_ver: u32) -> u8 {
902        0x19
903    }
904}
905
906impl Encode for ClientboundEntityHeadRotation {
907    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
908        dst.put_i32(self.entity_id);
909        dst.put_i8(self.head_yaw);
910        Ok(())
911    }
912}
913
914impl Decode for ClientboundEntityHeadRotation {
915    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
916        need(src, 4 + 1)?;
917        Ok(Self {
918            entity_id: src.get_i32(),
919            head_yaw: src.get_i8(),
920        })
921    }
922}
923
924#[derive(Debug, Clone, PartialEq)]
925pub struct ClientboundSetExperience {
926    pub experience_bar: f32,
927    pub level: i16,
928    pub total_experience: i16,
929}
930
931impl PacketId for ClientboundSetExperience {
932    fn packet_id(_ver: u32) -> u8 {
933        0x2B
934    }
935}
936
937impl Encode for ClientboundSetExperience {
938    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
939        dst.put_f32(self.experience_bar);
940        dst.put_i16(self.level);
941        dst.put_i16(self.total_experience);
942        Ok(())
943    }
944}
945
946impl Decode for ClientboundSetExperience {
947    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
948        need(src, 4 + 2 + 2)?;
949        Ok(Self {
950            experience_bar: src.get_f32(),
951            level: src.get_i16(),
952            total_experience: src.get_i16(),
953        })
954    }
955}
956
957#[derive(Debug, Clone, PartialEq)]
958pub struct ClientboundMapData {
959    pub item_damage: i16,
960    pub scale: i8,
961    pub data: Vec<u8>,
962}
963
964impl PacketId for ClientboundMapData {
965    fn packet_id(_ver: u32) -> u8 {
966        0x36
967    }
968}
969
970impl Encode for ClientboundMapData {
971    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
972        dst.put_i16(self.item_damage);
973        dst.put_i8(self.scale);
974        dst.extend_from_slice(&self.data);
975        Ok(())
976    }
977}
978
979impl Decode for ClientboundMapData {
980    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
981        need(src, 2 + 1)?;
982        let item_damage = src.get_i16();
983        let scale = src.get_i8();
984        let data = src.to_vec();
985        Ok(Self {
986            item_damage,
987            scale,
988            data,
989        })
990    }
991}
992
993#[derive(Debug, Clone, PartialEq)]
994pub struct ClientboundOpenWindow {
995    pub window_id: i8,
996    pub inventory_type: i8,
997    pub window_title: String,
998    pub slots_count: i8,
999    pub use_provided_title: bool,
1000}
1001
1002impl PacketId for ClientboundOpenWindow {
1003    fn packet_id(_ver: u32) -> u8 {
1004        0x64
1005    }
1006}
1007
1008impl Encode for ClientboundOpenWindow {
1009    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1010        dst.put_i8(self.window_id);
1011        dst.put_i8(self.inventory_type);
1012        encode_legacy_string(&self.window_title, dst);
1013        dst.put_i8(self.slots_count);
1014        dst.put_u8(self.use_provided_title as u8);
1015        Ok(())
1016    }
1017}
1018
1019impl Decode for ClientboundOpenWindow {
1020    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1021        let window_id = src.get_i8();
1022        let inventory_type = src.get_i8();
1023        let window_title = decode_legacy_string(src)?;
1024        need(src, 1 + 1)?;
1025        let slots_count = src.get_i8();
1026        let use_provided_title = src.get_u8() != 0;
1027        Ok(Self {
1028            window_id,
1029            inventory_type,
1030            window_title,
1031            slots_count,
1032            use_provided_title,
1033        })
1034    }
1035}
1036
1037#[derive(Debug, Clone, PartialEq)]
1038pub struct ClientboundCloseWindow {
1039    pub window_id: i8,
1040}
1041
1042impl PacketId for ClientboundCloseWindow {
1043    fn packet_id(_ver: u32) -> u8 {
1044        0x65
1045    }
1046}
1047
1048impl Encode for ClientboundCloseWindow {
1049    fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1050        dst.put_i8(self.window_id);
1051        Ok(())
1052    }
1053}
1054
1055impl Decode for ClientboundCloseWindow {
1056    fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1057        need(src, 1)?;
1058        Ok(Self {
1059            window_id: src.get_i8(),
1060        })
1061    }
1062}