1use bytes::{Buf, BufMut, Bytes, BytesMut};
2
3use crate::codec::{Decode, Encode, PacketId};
4use crate::error::ProtocolError;
5use crate::types::slot::LegacySlot;
6use crate::types::VarInt;
7
8pub use packets::{
9 ClientboundAwardStats, ClientboundBlockAction, ClientboundBlockDestroyStage,
10 ClientboundBlockEntityData, ClientboundBlockUpdate, ClientboundChangeDifficulty,
11 ClientboundChatMessage, ClientboundCommandSuggestions, ClientboundContainerClose,
12 ClientboundContainerSetContent, ClientboundContainerSetProperty, ClientboundContainerSetSlot,
13 ClientboundDisconnect, ClientboundEntityAnimation, ClientboundEntityEvent,
14 ClientboundExplosion, ClientboundForgetLevelChunk, ClientboundGameEvent, ClientboundJoinGame,
15 ClientboundKeepAlive, ClientboundLevelChunkWithLight, ClientboundLevelEvent,
16 ClientboundLevelParticles, ClientboundMapItemData, ClientboundMoveEntityPos,
17 ClientboundMoveEntityPosRot, ClientboundMoveEntityRot, ClientboundOpenScreen,
18 ClientboundOpenSignEditor, ClientboundPlayerAbilities, ClientboundPlayerCombatEnd,
19 ClientboundPlayerCombatEnter, ClientboundPlayerCombatKill, ClientboundPlayerInfoUpdate,
20 ClientboundPlayerPosition, ClientboundPluginMessage, ClientboundRemoveEntities,
21 ClientboundRemoveEntityEffect, ClientboundResetScore, ClientboundResourcePackPush,
22 ClientboundRespawn, ClientboundRotateHead, ClientboundSectionBlocksUpdate,
23 ClientboundSetEntityLink, ClientboundSetEntityMotion, ClientboundSetEquipment,
24 ClientboundSetExperience, ClientboundSetHealth, ClientboundSetHeldItem,
25 ClientboundSetScoreboardObjective, ClientboundSetScoreboardScore, ClientboundSetTime,
26 ClientboundSound, ClientboundSpawnEntity, ClientboundSpawnExperienceOrb, ClientboundSpawnMob,
27 ClientboundSpawnPlayer, ClientboundTabList, ClientboundTakeItemEntity,
28 ClientboundTeleportEntity, ClientboundUpdateAttributes, ClientboundUpdateEffects,
29 InteractAction, ServerboundAnimation, ServerboundChatMessage, ServerboundClickWindow,
30 ServerboundClickWindowButton, ServerboundClientSettings, ServerboundClientStatus,
31 ServerboundCloseWindow, ServerboundCommandSuggestion, ServerboundConfirmTransaction,
32 ServerboundCreativeInventoryAction, ServerboundEnchantItem, ServerboundEntityAction,
33 ServerboundHeldItemChange, ServerboundInteract, ServerboundKeepAlive, ServerboundMovePlayerPos,
34 ServerboundMovePlayerPosRot, ServerboundMovePlayerRot, ServerboundMovePlayerStatusOnly,
35 ServerboundPlayerAbilities, ServerboundPlayerAction, ServerboundPlayerBlockPlacement,
36 ServerboundPluginMessage, ServerboundResourcePackStatus, ServerboundSteerVehicle,
37 ServerboundUpdateSign,
38};
39
40mod packets {
41 use super::*;
42
43 fn encode_str(s: &str, dst: &mut BytesMut) -> Result<(), ProtocolError> {
44 let bytes = s.as_bytes();
45 VarInt(bytes.len() as i32).encode(dst)?;
46 dst.put_slice(bytes);
47 Ok(())
48 }
49
50 fn decode_str(src: &mut Bytes, ctx: &'static str) -> Result<String, ProtocolError> {
51 let len = VarInt::decode(src)?.0 as usize;
52 if src.remaining() < len {
53 return Err(ProtocolError::Io(std::io::Error::new(
54 std::io::ErrorKind::UnexpectedEof,
55 format!("Missing bytes for {ctx}"),
56 )));
57 }
58 let mut b = vec![0u8; len];
59 src.copy_to_slice(&mut b);
60 String::from_utf8(b).map_err(|_| {
61 ProtocolError::Io(std::io::Error::new(
62 std::io::ErrorKind::InvalidData,
63 format!("Invalid UTF-8 in {ctx}"),
64 ))
65 })
66 }
67
68 fn need(src: &Bytes, n: usize) -> Result<(), ProtocolError> {
69 if src.remaining() < n {
70 Err(ProtocolError::Io(std::io::Error::new(
71 std::io::ErrorKind::UnexpectedEof,
72 format!("Need {n} bytes, have {}", src.remaining()),
73 )))
74 } else {
75 Ok(())
76 }
77 }
78
79 macro_rules! raw_packet {
82 ($name:ident, $id:expr) => {
83 #[derive(Debug, Clone, PartialEq)]
84 pub struct $name {
85 pub raw: Vec<u8>,
86 }
87 impl PacketId for $name {
88 fn packet_id(_ver: u32) -> u8 {
89 $id
90 }
91 }
92 impl Encode for $name {
93 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
94 dst.put_slice(&self.raw);
95 Ok(())
96 }
97 }
98 impl Decode for $name {
99 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
100 let len = src.remaining();
101 let mut raw = vec![0u8; len];
102 src.copy_to_slice(&mut raw);
103 Ok(Self { raw })
104 }
105 }
106 };
107 }
108
109 #[derive(Debug, Clone, PartialEq)]
112 pub struct ClientboundKeepAlive {
113 pub keep_alive_id: VarInt,
114 }
115
116 impl PacketId for ClientboundKeepAlive {
117 fn packet_id(_ver: u32) -> u8 {
118 0x00
119 }
120 }
121
122 impl Encode for ClientboundKeepAlive {
123 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
124 self.keep_alive_id.encode(dst)
125 }
126 }
127
128 impl Decode for ClientboundKeepAlive {
129 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
130 Ok(Self {
131 keep_alive_id: VarInt::decode(src)?,
132 })
133 }
134 }
135
136 #[derive(Debug, Clone, PartialEq)]
137 pub struct ServerboundKeepAlive {
138 pub keep_alive_id: VarInt,
139 }
140
141 impl PacketId for ServerboundKeepAlive {
142 fn packet_id(_ver: u32) -> u8 {
143 0x00
144 }
145 }
146
147 impl Encode for ServerboundKeepAlive {
148 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
149 self.keep_alive_id.encode(dst)
150 }
151 }
152
153 impl Decode for ServerboundKeepAlive {
154 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
155 Ok(Self {
156 keep_alive_id: VarInt::decode(src)?,
157 })
158 }
159 }
160
161 #[derive(Debug, Clone, PartialEq)]
164 pub struct ClientboundJoinGame {
165 pub entity_id: i32,
166 pub game_mode: u8,
167 pub dimension: i8,
168 pub difficulty: u8,
169 pub max_players: u8,
170 pub level_type: String,
171 pub reduced_debug_info: bool,
172 }
173
174 impl PacketId for ClientboundJoinGame {
175 fn packet_id(_ver: u32) -> u8 {
176 0x01
177 }
178 }
179
180 impl Encode for ClientboundJoinGame {
181 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
182 dst.put_i32(self.entity_id);
183 dst.put_u8(self.game_mode);
184 dst.put_i8(self.dimension);
185 dst.put_u8(self.difficulty);
186 dst.put_u8(self.max_players);
187 encode_str(&self.level_type, dst)?;
188 dst.put_u8(self.reduced_debug_info as u8);
189 Ok(())
190 }
191 }
192
193 impl Decode for ClientboundJoinGame {
194 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
195 need(src, 4 + 1 + 1 + 1 + 1)?;
196 let entity_id = src.get_i32();
197 let game_mode = src.get_u8();
198 let dimension = src.get_i8();
199 let difficulty = src.get_u8();
200 let max_players = src.get_u8();
201 let level_type = decode_str(src, "ClientboundJoinGame level_type")?;
202 need(src, 1)?;
203 let reduced_debug_info = src.get_u8() != 0;
204 Ok(Self {
205 entity_id,
206 game_mode,
207 dimension,
208 difficulty,
209 max_players,
210 level_type,
211 reduced_debug_info,
212 })
213 }
214 }
215
216 #[derive(Debug, Clone, PartialEq)]
219 pub struct ClientboundChatMessage {
220 pub json_message: String,
221 pub position: u8,
222 }
223
224 impl PacketId for ClientboundChatMessage {
225 fn packet_id(_ver: u32) -> u8 {
226 0x02
227 }
228 }
229
230 impl Encode for ClientboundChatMessage {
231 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
232 encode_str(&self.json_message, dst)?;
233 dst.put_u8(self.position);
234 Ok(())
235 }
236 }
237
238 impl Decode for ClientboundChatMessage {
239 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
240 let json_message = decode_str(src, "ClientboundChatMessage json_message")?;
241 need(src, 1)?;
242 Ok(Self {
243 json_message,
244 position: src.get_u8(),
245 })
246 }
247 }
248
249 #[derive(Debug, Clone, PartialEq)]
250 pub struct ServerboundChatMessage {
251 pub message: String,
252 }
253
254 impl PacketId for ServerboundChatMessage {
255 fn packet_id(_ver: u32) -> u8 {
256 0x01
257 }
258 }
259
260 impl Encode for ServerboundChatMessage {
261 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
262 encode_str(&self.message, dst)
263 }
264 }
265
266 impl Decode for ServerboundChatMessage {
267 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
268 Ok(Self {
269 message: decode_str(src, "ServerboundChatMessage message")?,
270 })
271 }
272 }
273
274 #[derive(Debug, Clone, PartialEq)]
277 pub struct ClientboundRespawn {
278 pub dimension: i32,
279 pub difficulty: u8,
280 pub game_mode: u8,
281 pub level_type: String,
282 }
283
284 impl PacketId for ClientboundRespawn {
285 fn packet_id(_ver: u32) -> u8 {
286 0x07
287 }
288 }
289
290 impl Encode for ClientboundRespawn {
291 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
292 dst.put_i32(self.dimension);
293 dst.put_u8(self.difficulty);
294 dst.put_u8(self.game_mode);
295 encode_str(&self.level_type, dst)
296 }
297 }
298
299 impl Decode for ClientboundRespawn {
300 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
301 need(src, 4 + 1 + 1)?;
302 let dimension = src.get_i32();
303 let difficulty = src.get_u8();
304 let game_mode = src.get_u8();
305 let level_type = decode_str(src, "ClientboundRespawn level_type")?;
306 Ok(Self {
307 dimension,
308 difficulty,
309 game_mode,
310 level_type,
311 })
312 }
313 }
314
315 #[derive(Debug, Clone, PartialEq)]
319 pub struct ClientboundPlayerPosition {
320 pub x: f64,
321 pub head_y: f64,
322 pub z: f64,
323 pub yaw: f32,
324 pub pitch: f32,
325 pub flags: u8,
326 }
327
328 impl PacketId for ClientboundPlayerPosition {
329 fn packet_id(_ver: u32) -> u8 {
330 0x08
331 }
332 }
333
334 impl Encode for ClientboundPlayerPosition {
335 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
336 dst.put_f64(self.x);
337 dst.put_f64(self.head_y);
338 dst.put_f64(self.z);
339 dst.put_f32(self.yaw);
340 dst.put_f32(self.pitch);
341 dst.put_u8(self.flags);
342 Ok(())
343 }
344 }
345
346 impl Decode for ClientboundPlayerPosition {
347 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
348 need(src, 8 + 8 + 8 + 4 + 4 + 1)?;
349 Ok(Self {
350 x: src.get_f64(),
351 head_y: src.get_f64(),
352 z: src.get_f64(),
353 yaw: src.get_f32(),
354 pitch: src.get_f32(),
355 flags: src.get_u8(),
356 })
357 }
358 }
359
360 #[derive(Debug, Clone, PartialEq)]
363 pub struct ClientboundDisconnect {
364 pub reason: String,
365 }
366
367 impl PacketId for ClientboundDisconnect {
368 fn packet_id(_ver: u32) -> u8 {
369 0x40
370 }
371 }
372
373 impl Encode for ClientboundDisconnect {
374 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
375 encode_str(&self.reason, dst)
376 }
377 }
378
379 impl Decode for ClientboundDisconnect {
380 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
381 Ok(Self {
382 reason: decode_str(src, "ClientboundDisconnect reason")?,
383 })
384 }
385 }
386
387 #[derive(Debug, Clone, PartialEq)]
391 pub struct ClientboundPluginMessage {
392 pub channel: String,
393 pub data: Vec<u8>,
394 }
395
396 impl PacketId for ClientboundPluginMessage {
397 fn packet_id(_ver: u32) -> u8 {
398 0x3F
399 }
400 }
401
402 impl Encode for ClientboundPluginMessage {
403 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
404 encode_str(&self.channel, dst)?;
405 dst.put_i16(self.data.len() as i16);
406 dst.put_slice(&self.data);
407 Ok(())
408 }
409 }
410
411 impl Decode for ClientboundPluginMessage {
412 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
413 let channel = decode_str(src, "ClientboundPluginMessage channel")?;
414 need(src, 2)?;
415 let data_len = src.get_i16() as usize;
416 need(src, data_len)?;
417 let mut data = vec![0u8; data_len];
418 src.copy_to_slice(&mut data);
419 Ok(Self { channel, data })
420 }
421 }
422
423 #[derive(Debug, Clone, PartialEq)]
424 pub struct ServerboundPluginMessage {
425 pub channel: String,
426 pub data: Vec<u8>,
427 }
428
429 impl PacketId for ServerboundPluginMessage {
430 fn packet_id(_ver: u32) -> u8 {
431 0x17
432 }
433 }
434
435 impl Encode for ServerboundPluginMessage {
436 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
437 encode_str(&self.channel, dst)?;
438 dst.put_i16(self.data.len() as i16);
439 dst.put_slice(&self.data);
440 Ok(())
441 }
442 }
443
444 impl Decode for ServerboundPluginMessage {
445 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
446 let channel = decode_str(src, "ServerboundPluginMessage channel")?;
447 need(src, 2)?;
448 let data_len = src.get_i16() as usize;
449 need(src, data_len)?;
450 let mut data = vec![0u8; data_len];
451 src.copy_to_slice(&mut data);
452 Ok(Self { channel, data })
453 }
454 }
455
456 #[derive(Debug, Clone, PartialEq)]
460 pub enum InteractAction {
461 Interact,
462 Attack,
463 InteractAt {
464 target_x: f32,
465 target_y: f32,
466 target_z: f32,
467 },
468 }
469
470 #[derive(Debug, Clone, PartialEq)]
471 pub struct ServerboundInteract {
472 pub entity_id: VarInt,
473 pub action: InteractAction,
474 }
475
476 impl PacketId for ServerboundInteract {
477 fn packet_id(_ver: u32) -> u8 {
478 0x02
479 }
480 }
481
482 impl Encode for ServerboundInteract {
483 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
484 self.entity_id.encode(dst)?;
485 match &self.action {
486 InteractAction::Interact => {
487 VarInt(0).encode(dst)?;
488 },
489 InteractAction::Attack => {
490 VarInt(1).encode(dst)?;
491 },
492 InteractAction::InteractAt {
493 target_x,
494 target_y,
495 target_z,
496 } => {
497 VarInt(2).encode(dst)?;
498 dst.put_f32(*target_x);
499 dst.put_f32(*target_y);
500 dst.put_f32(*target_z);
501 },
502 }
503 Ok(())
504 }
505 }
506
507 impl Decode for ServerboundInteract {
508 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
509 let entity_id = VarInt::decode(src)?;
510 let action = match VarInt::decode(src)?.0 {
511 0 => InteractAction::Interact,
512 1 => InteractAction::Attack,
513 2 => {
514 need(src, 4 + 4 + 4)?;
515 InteractAction::InteractAt {
516 target_x: src.get_f32(),
517 target_y: src.get_f32(),
518 target_z: src.get_f32(),
519 }
520 },
521 _ => {
522 return Err(ProtocolError::Io(std::io::Error::new(
523 std::io::ErrorKind::InvalidData,
524 "Unknown ServerboundInteract action type",
525 )))
526 },
527 };
528 Ok(Self { entity_id, action })
529 }
530 }
531
532 #[derive(Debug, Clone, PartialEq)]
535 pub struct ServerboundMovePlayerPos {
536 pub x: f64,
537 pub feet_y: f64,
538 pub z: f64,
539 pub on_ground: bool,
540 }
541
542 impl PacketId for ServerboundMovePlayerPos {
543 fn packet_id(_ver: u32) -> u8 {
544 0x04
545 }
546 }
547
548 impl Encode for ServerboundMovePlayerPos {
549 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
550 dst.put_f64(self.x);
551 dst.put_f64(self.feet_y);
552 dst.put_f64(self.z);
553 dst.put_u8(self.on_ground as u8);
554 Ok(())
555 }
556 }
557
558 impl Decode for ServerboundMovePlayerPos {
559 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
560 need(src, 8 + 8 + 8 + 1)?;
561 Ok(Self {
562 x: src.get_f64(),
563 feet_y: src.get_f64(),
564 z: src.get_f64(),
565 on_ground: src.get_u8() != 0,
566 })
567 }
568 }
569
570 #[derive(Debug, Clone, PartialEq)]
571 pub struct ServerboundMovePlayerRot {
572 pub yaw: f32,
573 pub pitch: f32,
574 pub on_ground: bool,
575 }
576
577 impl PacketId for ServerboundMovePlayerRot {
578 fn packet_id(_ver: u32) -> u8 {
579 0x05
580 }
581 }
582
583 impl Encode for ServerboundMovePlayerRot {
584 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
585 dst.put_f32(self.yaw);
586 dst.put_f32(self.pitch);
587 dst.put_u8(self.on_ground as u8);
588 Ok(())
589 }
590 }
591
592 impl Decode for ServerboundMovePlayerRot {
593 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
594 need(src, 4 + 4 + 1)?;
595 Ok(Self {
596 yaw: src.get_f32(),
597 pitch: src.get_f32(),
598 on_ground: src.get_u8() != 0,
599 })
600 }
601 }
602
603 #[derive(Debug, Clone, PartialEq)]
604 pub struct ServerboundMovePlayerPosRot {
605 pub x: f64,
606 pub feet_y: f64,
607 pub z: f64,
608 pub yaw: f32,
609 pub pitch: f32,
610 pub on_ground: bool,
611 }
612
613 impl PacketId for ServerboundMovePlayerPosRot {
614 fn packet_id(_ver: u32) -> u8 {
615 0x06
616 }
617 }
618
619 impl Encode for ServerboundMovePlayerPosRot {
620 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
621 dst.put_f64(self.x);
622 dst.put_f64(self.feet_y);
623 dst.put_f64(self.z);
624 dst.put_f32(self.yaw);
625 dst.put_f32(self.pitch);
626 dst.put_u8(self.on_ground as u8);
627 Ok(())
628 }
629 }
630
631 impl Decode for ServerboundMovePlayerPosRot {
632 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
633 need(src, 8 + 8 + 8 + 4 + 4 + 1)?;
634 Ok(Self {
635 x: src.get_f64(),
636 feet_y: src.get_f64(),
637 z: src.get_f64(),
638 yaw: src.get_f32(),
639 pitch: src.get_f32(),
640 on_ground: src.get_u8() != 0,
641 })
642 }
643 }
644
645 #[derive(Debug, Clone, PartialEq)]
646 pub struct ClientboundSpawnMob {
647 pub entity_id: VarInt,
648 pub kind: u8, pub x: i32, pub y: i32, pub z: i32, pub pitch: u8,
653 pub yaw: u8,
654 pub head_pitch: u8,
655 pub velocity_x: i16,
656 pub velocity_y: i16,
657 pub velocity_z: i16,
658 pub metadata: Vec<u8>, }
660
661 impl PacketId for ClientboundSpawnMob {
662 fn packet_id(_ver: u32) -> u8 {
663 0x0F }
665 }
666
667 impl Encode for ClientboundSpawnMob {
668 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
669 self.entity_id.encode(dst)?;
670 dst.put_u8(self.kind);
671 dst.put_i32(self.x);
672 dst.put_i32(self.y);
673 dst.put_i32(self.z);
674 dst.put_u8(self.pitch);
675 dst.put_u8(self.yaw);
676 dst.put_u8(self.head_pitch);
677 dst.put_i16(self.velocity_x);
678 dst.put_i16(self.velocity_y);
679 dst.put_i16(self.velocity_z);
680
681 dst.put_slice(&self.metadata);
683 Ok(())
684 }
685 }
686
687 #[derive(Debug, Clone, PartialEq)]
690 pub struct ClientboundSetEquipment {
691 pub entity_id: i32,
692 pub slot: i16,
693 pub item: LegacySlot,
694 }
695
696 impl PacketId for ClientboundSetEquipment {
697 fn packet_id(_ver: u32) -> u8 {
698 0x04
699 }
700 }
701
702 impl Encode for ClientboundSetEquipment {
703 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
704 dst.put_i32(self.entity_id);
705 dst.put_i16(self.slot);
706 self.item.encode(dst)?;
707 Ok(())
708 }
709 }
710
711 impl Decode for ClientboundSetEquipment {
712 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
713 need(src, 4 + 2)?;
714 let entity_id = src.get_i32();
715 let slot = src.get_i16();
716 let item = LegacySlot::decode(src)?;
717 Ok(Self {
718 entity_id,
719 slot,
720 item,
721 })
722 }
723 }
724
725 #[derive(Debug, Clone, PartialEq)]
728 pub struct ClientboundEntityAnimation {
729 pub entity_id: i32,
730 pub animation: i8,
731 }
732
733 impl PacketId for ClientboundEntityAnimation {
734 fn packet_id(_ver: u32) -> u8 {
735 0x0B
736 }
737 }
738
739 impl Encode for ClientboundEntityAnimation {
740 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
741 dst.put_i32(self.entity_id);
742 dst.put_i8(self.animation);
743 Ok(())
744 }
745 }
746
747 impl Decode for ClientboundEntityAnimation {
748 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
749 need(src, 4 + 1)?;
750 Ok(Self {
751 entity_id: src.get_i32(),
752 animation: src.get_i8(),
753 })
754 }
755 }
756
757 #[derive(Debug, Clone, PartialEq)]
760 pub struct ClientboundTakeItemEntity {
761 pub collected_entity_id: i32,
762 pub collector_entity_id: i32,
763 }
764
765 impl PacketId for ClientboundTakeItemEntity {
766 fn packet_id(_ver: u32) -> u8 {
767 0x0D
768 }
769 }
770
771 impl Encode for ClientboundTakeItemEntity {
772 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
773 dst.put_i32(self.collected_entity_id);
774 dst.put_i32(self.collector_entity_id);
775 Ok(())
776 }
777 }
778
779 impl Decode for ClientboundTakeItemEntity {
780 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
781 need(src, 4 + 4)?;
782 Ok(Self {
783 collected_entity_id: src.get_i32(),
784 collector_entity_id: src.get_i32(),
785 })
786 }
787 }
788
789 #[derive(Debug, Clone, PartialEq)]
792 pub struct ClientboundSpawnExperienceOrb {
793 pub entity_id: i32,
794 pub x: i32,
795 pub y: i32,
796 pub z: i32,
797 pub count: i16,
798 }
799
800 impl PacketId for ClientboundSpawnExperienceOrb {
801 fn packet_id(_ver: u32) -> u8 {
802 0x11
803 }
804 }
805
806 impl Encode for ClientboundSpawnExperienceOrb {
807 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
808 dst.put_i32(self.entity_id);
809 dst.put_i32(self.x);
810 dst.put_i32(self.y);
811 dst.put_i32(self.z);
812 dst.put_i16(self.count);
813 Ok(())
814 }
815 }
816
817 impl Decode for ClientboundSpawnExperienceOrb {
818 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
819 need(src, 4 + 4 + 4 + 4 + 2)?;
820 Ok(Self {
821 entity_id: src.get_i32(),
822 x: src.get_i32(),
823 y: src.get_i32(),
824 z: src.get_i32(),
825 count: src.get_i16(),
826 })
827 }
828 }
829
830 #[derive(Debug, Clone, PartialEq)]
833 pub struct ClientboundSetEntityMotion {
834 pub entity_id: i32,
835 pub mot_x: i16,
836 pub mot_y: i16,
837 pub mot_z: i16,
838 }
839
840 impl PacketId for ClientboundSetEntityMotion {
841 fn packet_id(_ver: u32) -> u8 {
842 0x12
843 }
844 }
845
846 impl Encode for ClientboundSetEntityMotion {
847 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
848 dst.put_i32(self.entity_id);
849 dst.put_i16(self.mot_x);
850 dst.put_i16(self.mot_y);
851 dst.put_i16(self.mot_z);
852 Ok(())
853 }
854 }
855
856 impl Decode for ClientboundSetEntityMotion {
857 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
858 need(src, 4 + 2 + 2 + 2)?;
859 Ok(Self {
860 entity_id: src.get_i32(),
861 mot_x: src.get_i16(),
862 mot_y: src.get_i16(),
863 mot_z: src.get_i16(),
864 })
865 }
866 }
867
868 #[derive(Debug, Clone, PartialEq)]
871 pub struct ClientboundRemoveEntities {
872 pub entity_ids: Vec<i32>,
873 }
874
875 impl PacketId for ClientboundRemoveEntities {
876 fn packet_id(_ver: u32) -> u8 {
877 0x13
878 }
879 }
880
881 impl Encode for ClientboundRemoveEntities {
882 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
883 VarInt(self.entity_ids.len() as i32).encode(dst)?;
884 for id in &self.entity_ids {
885 dst.put_i32(*id);
886 }
887 Ok(())
888 }
889 }
890
891 impl Decode for ClientboundRemoveEntities {
892 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
893 let count = VarInt::decode(src)?.0 as usize;
894 need(src, count * 4)?;
895 let mut entity_ids = Vec::with_capacity(count);
896 for _ in 0..count {
897 entity_ids.push(src.get_i32());
898 }
899 Ok(Self { entity_ids })
900 }
901 }
902
903 #[derive(Debug, Clone, PartialEq)]
906 pub struct ClientboundMoveEntityPos {
907 pub entity_id: i32,
908 pub dx: i8,
909 pub dy: i8,
910 pub dz: i8,
911 }
912
913 impl PacketId for ClientboundMoveEntityPos {
914 fn packet_id(_ver: u32) -> u8 {
915 0x15
916 }
917 }
918
919 impl Encode for ClientboundMoveEntityPos {
920 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
921 dst.put_i32(self.entity_id);
922 dst.put_i8(self.dx);
923 dst.put_i8(self.dy);
924 dst.put_i8(self.dz);
925 Ok(())
926 }
927 }
928
929 impl Decode for ClientboundMoveEntityPos {
930 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
931 need(src, 4 + 1 + 1 + 1)?;
932 Ok(Self {
933 entity_id: src.get_i32(),
934 dx: src.get_i8(),
935 dy: src.get_i8(),
936 dz: src.get_i8(),
937 })
938 }
939 }
940
941 #[derive(Debug, Clone, PartialEq)]
944 pub struct ClientboundMoveEntityRot {
945 pub entity_id: i32,
946 pub yaw: i8,
947 pub pitch: i8,
948 }
949
950 impl PacketId for ClientboundMoveEntityRot {
951 fn packet_id(_ver: u32) -> u8 {
952 0x16
953 }
954 }
955
956 impl Encode for ClientboundMoveEntityRot {
957 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
958 dst.put_i32(self.entity_id);
959 dst.put_i8(self.yaw);
960 dst.put_i8(self.pitch);
961 Ok(())
962 }
963 }
964
965 impl Decode for ClientboundMoveEntityRot {
966 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
967 need(src, 4 + 1 + 1)?;
968 Ok(Self {
969 entity_id: src.get_i32(),
970 yaw: src.get_i8(),
971 pitch: src.get_i8(),
972 })
973 }
974 }
975
976 #[derive(Debug, Clone, PartialEq)]
979 pub struct ClientboundMoveEntityPosRot {
980 pub entity_id: i32,
981 pub dx: i8,
982 pub dy: i8,
983 pub dz: i8,
984 pub yaw: i8,
985 pub pitch: i8,
986 }
987
988 impl PacketId for ClientboundMoveEntityPosRot {
989 fn packet_id(_ver: u32) -> u8 {
990 0x17
991 }
992 }
993
994 impl Encode for ClientboundMoveEntityPosRot {
995 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
996 dst.put_i32(self.entity_id);
997 dst.put_i8(self.dx);
998 dst.put_i8(self.dy);
999 dst.put_i8(self.dz);
1000 dst.put_i8(self.yaw);
1001 dst.put_i8(self.pitch);
1002 Ok(())
1003 }
1004 }
1005
1006 impl Decode for ClientboundMoveEntityPosRot {
1007 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1008 need(src, 4 + 1 + 1 + 1 + 1 + 1)?;
1009 Ok(Self {
1010 entity_id: src.get_i32(),
1011 dx: src.get_i8(),
1012 dy: src.get_i8(),
1013 dz: src.get_i8(),
1014 yaw: src.get_i8(),
1015 pitch: src.get_i8(),
1016 })
1017 }
1018 }
1019
1020 #[derive(Debug, Clone, PartialEq)]
1023 pub struct ClientboundTeleportEntity {
1024 pub entity_id: i32,
1025 pub x: i32,
1026 pub y: i32,
1027 pub z: i32,
1028 pub yaw: i8,
1029 pub pitch: i8,
1030 }
1031
1032 impl PacketId for ClientboundTeleportEntity {
1033 fn packet_id(_ver: u32) -> u8 {
1034 0x18
1035 }
1036 }
1037
1038 impl Encode for ClientboundTeleportEntity {
1039 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1040 dst.put_i32(self.entity_id);
1041 dst.put_i32(self.x);
1042 dst.put_i32(self.y);
1043 dst.put_i32(self.z);
1044 dst.put_i8(self.yaw);
1045 dst.put_i8(self.pitch);
1046 Ok(())
1047 }
1048 }
1049
1050 impl Decode for ClientboundTeleportEntity {
1051 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1052 need(src, 4 + 4 + 4 + 4 + 1 + 1)?;
1053 Ok(Self {
1054 entity_id: src.get_i32(),
1055 x: src.get_i32(),
1056 y: src.get_i32(),
1057 z: src.get_i32(),
1058 yaw: src.get_i8(),
1059 pitch: src.get_i8(),
1060 })
1061 }
1062 }
1063
1064 #[derive(Debug, Clone, PartialEq)]
1067 pub struct ClientboundRotateHead {
1068 pub entity_id: i32,
1069 pub head_yaw: i8,
1070 }
1071
1072 impl PacketId for ClientboundRotateHead {
1073 fn packet_id(_ver: u32) -> u8 {
1074 0x19
1075 }
1076 }
1077
1078 impl Encode for ClientboundRotateHead {
1079 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1080 dst.put_i32(self.entity_id);
1081 dst.put_i8(self.head_yaw);
1082 Ok(())
1083 }
1084 }
1085
1086 impl Decode for ClientboundRotateHead {
1087 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1088 need(src, 4 + 1)?;
1089 Ok(Self {
1090 entity_id: src.get_i32(),
1091 head_yaw: src.get_i8(),
1092 })
1093 }
1094 }
1095
1096 #[derive(Debug, Clone, PartialEq)]
1099 pub struct ClientboundEntityEvent {
1100 pub entity_id: i32,
1101 pub event_id: i8,
1102 }
1103
1104 impl PacketId for ClientboundEntityEvent {
1105 fn packet_id(_ver: u32) -> u8 {
1106 0x1A
1107 }
1108 }
1109
1110 impl Encode for ClientboundEntityEvent {
1111 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1112 dst.put_i32(self.entity_id);
1113 dst.put_i8(self.event_id);
1114 Ok(())
1115 }
1116 }
1117
1118 impl Decode for ClientboundEntityEvent {
1119 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1120 need(src, 4 + 1)?;
1121 Ok(Self {
1122 entity_id: src.get_i32(),
1123 event_id: src.get_i8(),
1124 })
1125 }
1126 }
1127
1128 #[derive(Debug, Clone, PartialEq)]
1131 pub struct ClientboundSetEntityLink {
1132 pub entity_id: i32,
1133 pub vehicle_id: i32,
1134 }
1135
1136 impl PacketId for ClientboundSetEntityLink {
1137 fn packet_id(_ver: u32) -> u8 {
1138 0x1B
1139 }
1140 }
1141
1142 impl Encode for ClientboundSetEntityLink {
1143 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1144 dst.put_i32(self.entity_id);
1145 dst.put_i32(self.vehicle_id);
1146 Ok(())
1147 }
1148 }
1149
1150 impl Decode for ClientboundSetEntityLink {
1151 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1152 need(src, 4 + 4)?;
1153 Ok(Self {
1154 entity_id: src.get_i32(),
1155 vehicle_id: src.get_i32(),
1156 })
1157 }
1158 }
1159
1160 #[derive(Debug, Clone, PartialEq)]
1163 pub struct ClientboundUpdateEffects {
1164 pub entity_id: i32,
1165 pub effect_id: i8,
1166 pub amplifier: i8,
1167 pub duration: i16,
1168 }
1169
1170 impl PacketId for ClientboundUpdateEffects {
1171 fn packet_id(_ver: u32) -> u8 {
1172 0x1D
1173 }
1174 }
1175
1176 impl Encode for ClientboundUpdateEffects {
1177 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1178 dst.put_i32(self.entity_id);
1179 dst.put_i8(self.effect_id);
1180 dst.put_i8(self.amplifier);
1181 dst.put_i16(self.duration);
1182 Ok(())
1183 }
1184 }
1185
1186 impl Decode for ClientboundUpdateEffects {
1187 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1188 need(src, 4 + 1 + 1 + 2)?;
1189 Ok(Self {
1190 entity_id: src.get_i32(),
1191 effect_id: src.get_i8(),
1192 amplifier: src.get_i8(),
1193 duration: src.get_i16(),
1194 })
1195 }
1196 }
1197
1198 #[derive(Debug, Clone, PartialEq)]
1201 pub struct ClientboundRemoveEntityEffect {
1202 pub entity_id: i32,
1203 pub effect_id: i8,
1204 }
1205
1206 impl PacketId for ClientboundRemoveEntityEffect {
1207 fn packet_id(_ver: u32) -> u8 {
1208 0x1E
1209 }
1210 }
1211
1212 impl Encode for ClientboundRemoveEntityEffect {
1213 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1214 dst.put_i32(self.entity_id);
1215 dst.put_i8(self.effect_id);
1216 Ok(())
1217 }
1218 }
1219
1220 impl Decode for ClientboundRemoveEntityEffect {
1221 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1222 need(src, 4 + 1)?;
1223 Ok(Self {
1224 entity_id: src.get_i32(),
1225 effect_id: src.get_i8(),
1226 })
1227 }
1228 }
1229
1230 #[derive(Debug, Clone, PartialEq)]
1233 pub struct ClientboundUpdateAttributes {
1234 pub entity_id: i32,
1235 pub data: Vec<u8>,
1236 }
1237
1238 impl PacketId for ClientboundUpdateAttributes {
1239 fn packet_id(_ver: u32) -> u8 {
1240 0x20
1241 }
1242 }
1243
1244 impl Encode for ClientboundUpdateAttributes {
1245 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1246 dst.put_i32(self.entity_id);
1247 dst.extend_from_slice(&self.data);
1248 Ok(())
1249 }
1250 }
1251
1252 impl Decode for ClientboundUpdateAttributes {
1253 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1254 need(src, 4)?;
1255 let entity_id = src.get_i32();
1256 let data = src.to_vec();
1257 Ok(Self { entity_id, data })
1258 }
1259 }
1260
1261 #[derive(Debug, Clone, PartialEq)]
1264 pub struct ClientboundLevelChunkWithLight {
1265 pub chunk_x: i32,
1266 pub chunk_z: i32,
1267 pub continuous: bool,
1268 pub primary_bitmap: i16,
1269 pub add_bitmap: i16,
1270 pub compressed_data: Vec<u8>,
1271 }
1272
1273 impl PacketId for ClientboundLevelChunkWithLight {
1274 fn packet_id(_ver: u32) -> u8 {
1275 0x21
1276 }
1277 }
1278
1279 impl Encode for ClientboundLevelChunkWithLight {
1280 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1281 dst.put_i32(self.chunk_x);
1282 dst.put_i32(self.chunk_z);
1283 dst.put_u8(self.continuous as u8);
1284 dst.put_i16(self.primary_bitmap);
1285 dst.put_i16(self.add_bitmap);
1286 dst.put_i32(self.compressed_data.len() as i32);
1287 dst.extend_from_slice(&self.compressed_data);
1288 Ok(())
1289 }
1290 }
1291
1292 impl Decode for ClientboundLevelChunkWithLight {
1293 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1294 need(src, 4 + 4 + 1 + 2 + 2 + 4)?;
1295 let chunk_x = src.get_i32();
1296 let chunk_z = src.get_i32();
1297 let continuous = src.get_u8() != 0;
1298 let primary_bitmap = src.get_i16();
1299 let add_bitmap = src.get_i16();
1300 let data_len = src.get_i32() as usize;
1301 if src.remaining() < data_len {
1302 return Err(ProtocolError::UnexpectedEof);
1303 }
1304 let compressed_data = src.copy_to_bytes(data_len).to_vec();
1305 Ok(Self {
1306 chunk_x,
1307 chunk_z,
1308 continuous,
1309 primary_bitmap,
1310 add_bitmap,
1311 compressed_data,
1312 })
1313 }
1314 }
1315
1316 #[derive(Debug, Clone, PartialEq)]
1319 pub struct ClientboundSectionBlocksUpdate {
1320 pub chunk_x: i32,
1321 pub chunk_z: i32,
1322 pub record_count: i16,
1323 pub data: Vec<u8>,
1324 }
1325
1326 impl PacketId for ClientboundSectionBlocksUpdate {
1327 fn packet_id(_ver: u32) -> u8 {
1328 0x22
1329 }
1330 }
1331
1332 impl Encode for ClientboundSectionBlocksUpdate {
1333 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1334 dst.put_i32(self.chunk_x);
1335 dst.put_i32(self.chunk_z);
1336 dst.put_i16(self.record_count);
1337 dst.extend_from_slice(&self.data);
1338 Ok(())
1339 }
1340 }
1341
1342 impl Decode for ClientboundSectionBlocksUpdate {
1343 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1344 need(src, 4 + 4 + 2)?;
1345 let chunk_x = src.get_i32();
1346 let chunk_z = src.get_i32();
1347 let record_count = src.get_i16();
1348 let data = src.to_vec();
1349 Ok(Self {
1350 chunk_x,
1351 chunk_z,
1352 record_count,
1353 data,
1354 })
1355 }
1356 }
1357
1358 #[derive(Debug, Clone, PartialEq)]
1361 pub struct ClientboundBlockAction {
1362 pub x: i32,
1363 pub y: i16,
1364 pub z: i32,
1365 pub action_id: i8,
1366 pub action_param: i8,
1367 pub block_type: i32,
1368 }
1369
1370 impl PacketId for ClientboundBlockAction {
1371 fn packet_id(_ver: u32) -> u8 {
1372 0x24
1373 }
1374 }
1375
1376 impl Encode for ClientboundBlockAction {
1377 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1378 dst.put_i32(self.x);
1379 dst.put_i16(self.y);
1380 dst.put_i32(self.z);
1381 dst.put_i8(self.action_id);
1382 dst.put_i8(self.action_param);
1383 VarInt(self.block_type).encode(dst)?;
1384 Ok(())
1385 }
1386 }
1387
1388 impl Decode for ClientboundBlockAction {
1389 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1390 need(src, 4 + 2 + 4 + 1 + 1)?;
1391 Ok(Self {
1392 x: src.get_i32(),
1393 y: src.get_i16(),
1394 z: src.get_i32(),
1395 action_id: src.get_i8(),
1396 action_param: src.get_i8(),
1397 block_type: VarInt::decode(src)?.0,
1398 })
1399 }
1400 }
1401
1402 #[derive(Debug, Clone, PartialEq)]
1405 pub struct ClientboundBlockDestroyStage {
1406 pub x: i32,
1407 pub y: i8,
1408 pub z: i32,
1409 pub stage: i8,
1410 }
1411
1412 impl PacketId for ClientboundBlockDestroyStage {
1413 fn packet_id(_ver: u32) -> u8 {
1414 0x25
1415 }
1416 }
1417
1418 impl Encode for ClientboundBlockDestroyStage {
1419 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1420 dst.put_i32(self.x);
1421 dst.put_i8(self.y);
1422 dst.put_i32(self.z);
1423 dst.put_i8(self.stage);
1424 Ok(())
1425 }
1426 }
1427
1428 impl Decode for ClientboundBlockDestroyStage {
1429 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1430 need(src, 4 + 1 + 4 + 1)?;
1431 Ok(Self {
1432 x: src.get_i32(),
1433 y: src.get_i8(),
1434 z: src.get_i32(),
1435 stage: src.get_i8(),
1436 })
1437 }
1438 }
1439
1440 #[derive(Debug, Clone, PartialEq)]
1443 pub struct ClientboundForgetLevelChunk {
1444 pub chunk_x: i32,
1445 pub chunk_z: i32,
1446 }
1447
1448 impl PacketId for ClientboundForgetLevelChunk {
1449 fn packet_id(_ver: u32) -> u8 {
1450 0x26
1451 }
1452 }
1453
1454 impl Encode for ClientboundForgetLevelChunk {
1455 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1456 dst.put_i32(self.chunk_x);
1457 dst.put_i32(self.chunk_z);
1458 Ok(())
1459 }
1460 }
1461
1462 impl Decode for ClientboundForgetLevelChunk {
1463 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1464 need(src, 4 + 4)?;
1465 Ok(Self {
1466 chunk_x: src.get_i32(),
1467 chunk_z: src.get_i32(),
1468 })
1469 }
1470 }
1471
1472 #[derive(Debug, Clone, PartialEq)]
1475 pub struct ClientboundExplosion {
1476 pub x: f32,
1477 pub y: f32,
1478 pub z: f32,
1479 pub radius: f32,
1480 pub record_count: i32,
1481 pub records: Vec<u8>,
1482 pub player_motion_x: f32,
1483 pub player_motion_y: f32,
1484 pub player_motion_z: f32,
1485 }
1486
1487 impl PacketId for ClientboundExplosion {
1488 fn packet_id(_ver: u32) -> u8 {
1489 0x27
1490 }
1491 }
1492
1493 impl Encode for ClientboundExplosion {
1494 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1495 dst.put_f32(self.x);
1496 dst.put_f32(self.y);
1497 dst.put_f32(self.z);
1498 dst.put_f32(self.radius);
1499 dst.put_i32(self.record_count);
1500 dst.extend_from_slice(&self.records);
1501 dst.put_f32(self.player_motion_x);
1502 dst.put_f32(self.player_motion_y);
1503 dst.put_f32(self.player_motion_z);
1504 Ok(())
1505 }
1506 }
1507
1508 impl Decode for ClientboundExplosion {
1509 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1510 need(src, 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4)?;
1511 let x = src.get_f32();
1512 let y = src.get_f32();
1513 let z = src.get_f32();
1514 let radius = src.get_f32();
1515 let record_count = src.get_i32();
1516 let records_len = record_count as usize * 3;
1517 if src.remaining() < records_len + 12 {
1518 return Err(ProtocolError::UnexpectedEof);
1519 }
1520 let mut records = vec![0u8; records_len];
1521 src.copy_to_slice(&mut records);
1522 let player_motion_x = src.get_f32();
1523 let player_motion_y = src.get_f32();
1524 let player_motion_z = src.get_f32();
1525 Ok(Self {
1526 x,
1527 y,
1528 z,
1529 radius,
1530 record_count,
1531 records,
1532 player_motion_x,
1533 player_motion_y,
1534 player_motion_z,
1535 })
1536 }
1537 }
1538
1539 #[derive(Debug, Clone, PartialEq)]
1542 pub struct ClientboundLevelEvent {
1543 pub event_id: i32,
1544 pub x: i32,
1545 pub y: i32,
1546 pub z: i32,
1547 pub data: i32,
1548 }
1549
1550 impl PacketId for ClientboundLevelEvent {
1551 fn packet_id(_ver: u32) -> u8 {
1552 0x28
1553 }
1554 }
1555
1556 impl Encode for ClientboundLevelEvent {
1557 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1558 dst.put_i32(self.event_id);
1559 dst.put_i32(self.x);
1560 dst.put_i32(self.y);
1561 dst.put_i32(self.z);
1562 dst.put_i32(self.data);
1563 Ok(())
1564 }
1565 }
1566
1567 impl Decode for ClientboundLevelEvent {
1568 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1569 need(src, 4 + 4 + 4 + 4 + 4)?;
1570 Ok(Self {
1571 event_id: src.get_i32(),
1572 x: src.get_i32(),
1573 y: src.get_i32(),
1574 z: src.get_i32(),
1575 data: src.get_i32(),
1576 })
1577 }
1578 }
1579
1580 #[derive(Debug, Clone, PartialEq)]
1583 pub struct ClientboundLevelParticles {
1584 pub particle_id: i32,
1585 pub x: f32,
1586 pub y: f32,
1587 pub z: f32,
1588 pub offset_x: f32,
1589 pub offset_y: f32,
1590 pub offset_z: f32,
1591 pub particle_speed: f32,
1592 pub particle_count: i32,
1593 pub data: Vec<u8>,
1594 }
1595
1596 impl PacketId for ClientboundLevelParticles {
1597 fn packet_id(_ver: u32) -> u8 {
1598 0x2A
1599 }
1600 }
1601
1602 impl Encode for ClientboundLevelParticles {
1603 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1604 dst.put_i32(self.particle_id);
1605 dst.put_f32(self.x);
1606 dst.put_f32(self.y);
1607 dst.put_f32(self.z);
1608 dst.put_f32(self.offset_x);
1609 dst.put_f32(self.offset_y);
1610 dst.put_f32(self.offset_z);
1611 dst.put_f32(self.particle_speed);
1612 dst.put_i32(self.particle_count);
1613 dst.extend_from_slice(&self.data);
1614 Ok(())
1615 }
1616 }
1617
1618 impl Decode for ClientboundLevelParticles {
1619 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1620 need(src, 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4)?;
1621 let particle_id = src.get_i32();
1622 let x = src.get_f32();
1623 let y = src.get_f32();
1624 let z = src.get_f32();
1625 let offset_x = src.get_f32();
1626 let offset_y = src.get_f32();
1627 let offset_z = src.get_f32();
1628 let particle_speed = src.get_f32();
1629 let particle_count = src.get_i32();
1630 let data = src.to_vec();
1631 Ok(Self {
1632 particle_id,
1633 x,
1634 y,
1635 z,
1636 offset_x,
1637 offset_y,
1638 offset_z,
1639 particle_speed,
1640 particle_count,
1641 data,
1642 })
1643 }
1644 }
1645
1646 #[derive(Debug, Clone, PartialEq)]
1649 pub struct ClientboundGameEvent {
1650 pub event: u8,
1651 pub data: f32,
1652 }
1653
1654 impl PacketId for ClientboundGameEvent {
1655 fn packet_id(_ver: u32) -> u8 {
1656 0x2B
1657 }
1658 }
1659
1660 impl Encode for ClientboundGameEvent {
1661 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1662 dst.put_u8(self.event);
1663 dst.put_f32(self.data);
1664 Ok(())
1665 }
1666 }
1667
1668 impl Decode for ClientboundGameEvent {
1669 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1670 need(src, 1 + 4)?;
1671 Ok(Self {
1672 event: src.get_u8(),
1673 data: src.get_f32(),
1674 })
1675 }
1676 }
1677
1678 #[derive(Debug, Clone, PartialEq)]
1681 pub struct ClientboundOpenScreen {
1682 pub window_id: i8,
1683 pub window_type: String,
1684 pub window_title: String,
1685 pub slots_count: i8,
1686 }
1687
1688 impl PacketId for ClientboundOpenScreen {
1689 fn packet_id(_ver: u32) -> u8 {
1690 0x2D
1691 }
1692 }
1693
1694 impl Encode for ClientboundOpenScreen {
1695 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1696 dst.put_i8(self.window_id);
1697 encode_str(&self.window_type, dst)?;
1698 encode_str(&self.window_title, dst)?;
1699 dst.put_i8(self.slots_count);
1700 Ok(())
1701 }
1702 }
1703
1704 impl Decode for ClientboundOpenScreen {
1705 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1706 let window_id = src.get_i8();
1707 let window_type = decode_str(src, "ClientboundOpenScreen window_type")?;
1708 let window_title = decode_str(src, "ClientboundOpenScreen window_title")?;
1709 need(src, 1)?;
1710 let slots_count = src.get_i8();
1711 Ok(Self {
1712 window_id,
1713 window_type,
1714 window_title,
1715 slots_count,
1716 })
1717 }
1718 }
1719
1720 #[derive(Debug, Clone, PartialEq)]
1723 pub struct ClientboundContainerClose {
1724 pub window_id: i8,
1725 }
1726
1727 impl PacketId for ClientboundContainerClose {
1728 fn packet_id(_ver: u32) -> u8 {
1729 0x2E
1730 }
1731 }
1732
1733 impl Encode for ClientboundContainerClose {
1734 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1735 dst.put_i8(self.window_id);
1736 Ok(())
1737 }
1738 }
1739
1740 impl Decode for ClientboundContainerClose {
1741 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1742 need(src, 1)?;
1743 Ok(Self {
1744 window_id: src.get_i8(),
1745 })
1746 }
1747 }
1748
1749 #[derive(Debug, Clone, PartialEq)]
1752 pub struct ClientboundContainerSetProperty {
1753 pub window_id: i8,
1754 pub property: i16,
1755 pub value: i16,
1756 }
1757
1758 impl PacketId for ClientboundContainerSetProperty {
1759 fn packet_id(_ver: u32) -> u8 {
1760 0x31
1761 }
1762 }
1763
1764 impl Encode for ClientboundContainerSetProperty {
1765 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1766 dst.put_i8(self.window_id);
1767 dst.put_i16(self.property);
1768 dst.put_i16(self.value);
1769 Ok(())
1770 }
1771 }
1772
1773 impl Decode for ClientboundContainerSetProperty {
1774 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1775 need(src, 1 + 2 + 2)?;
1776 Ok(Self {
1777 window_id: src.get_i8(),
1778 property: src.get_i16(),
1779 value: src.get_i16(),
1780 })
1781 }
1782 }
1783
1784 #[derive(Debug, Clone, PartialEq)]
1787 pub struct ClientboundSetTime {
1788 pub age: i64,
1789 pub time: i64,
1790 }
1791
1792 impl PacketId for ClientboundSetTime {
1793 fn packet_id(_ver: u32) -> u8 {
1794 0x03
1795 }
1796 }
1797
1798 impl Encode for ClientboundSetTime {
1799 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1800 dst.put_i64(self.age);
1801 dst.put_i64(self.time);
1802 Ok(())
1803 }
1804 }
1805
1806 impl Decode for ClientboundSetTime {
1807 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1808 need(src, 8 + 8)?;
1809 Ok(Self {
1810 age: src.get_i64(),
1811 time: src.get_i64(),
1812 })
1813 }
1814 }
1815
1816 #[derive(Debug, Clone, PartialEq)]
1819 pub struct ClientboundSetHealth {
1820 pub health: f32,
1821 pub food: i16,
1822 pub food_saturation: f32,
1823 }
1824
1825 impl PacketId for ClientboundSetHealth {
1826 fn packet_id(_ver: u32) -> u8 {
1827 0x06
1828 }
1829 }
1830
1831 impl Encode for ClientboundSetHealth {
1832 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1833 dst.put_f32(self.health);
1834 dst.put_i16(self.food);
1835 dst.put_f32(self.food_saturation);
1836 Ok(())
1837 }
1838 }
1839
1840 impl Decode for ClientboundSetHealth {
1841 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1842 need(src, 4 + 2 + 4)?;
1843 Ok(Self {
1844 health: src.get_f32(),
1845 food: src.get_i16(),
1846 food_saturation: src.get_f32(),
1847 })
1848 }
1849 }
1850
1851 #[derive(Debug, Clone, PartialEq)]
1854 pub struct ClientboundSpawnPlayer {
1855 pub entity_id: i32,
1856 pub player_uuid: uuid::Uuid,
1857 pub username: String,
1858 pub x: i32,
1859 pub y: i32,
1860 pub z: i32,
1861 pub yaw: i8,
1862 pub pitch: i8,
1863 pub current_item: i16,
1864 }
1865
1866 impl PacketId for ClientboundSpawnPlayer {
1867 fn packet_id(_ver: u32) -> u8 {
1868 0x0C
1869 }
1870 }
1871
1872 impl Encode for ClientboundSpawnPlayer {
1873 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1874 dst.put_i32(self.entity_id);
1875 let (hi, lo) = self.player_uuid.as_u64_pair();
1876 dst.put_i64(hi as i64);
1877 dst.put_i64(lo as i64);
1878 encode_str(&self.username, dst)?;
1879 dst.put_i32(self.x);
1880 dst.put_i32(self.y);
1881 dst.put_i32(self.z);
1882 dst.put_i8(self.yaw);
1883 dst.put_i8(self.pitch);
1884 dst.put_i16(self.current_item);
1885 Ok(())
1886 }
1887 }
1888
1889 impl Decode for ClientboundSpawnPlayer {
1890 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1891 need(src, 4 + 8 + 8)?;
1892 let entity_id = src.get_i32();
1893 let hi = src.get_i64() as u64;
1894 let lo = src.get_i64() as u64;
1895 let player_uuid = uuid::Uuid::from_u64_pair(hi, lo);
1896 let username = decode_str(src, "ClientboundSpawnPlayer username")?;
1897 need(src, 4 + 4 + 4 + 1 + 1 + 2)?;
1898 Ok(Self {
1899 entity_id,
1900 player_uuid,
1901 username,
1902 x: src.get_i32(),
1903 y: src.get_i32(),
1904 z: src.get_i32(),
1905 yaw: src.get_i8(),
1906 pitch: src.get_i8(),
1907 current_item: src.get_i16(),
1908 })
1909 }
1910 }
1911
1912 #[derive(Debug, Clone, PartialEq)]
1915 pub struct ClientboundSpawnEntity {
1916 pub entity_id: i32,
1917 pub entity_type: i8,
1918 pub x: i32,
1919 pub y: i32,
1920 pub z: i32,
1921 pub yaw: i8,
1922 pub pitch: i8,
1923 pub head_pitch: i8,
1924 pub velocity_x: i16,
1925 pub velocity_y: i16,
1926 pub velocity_z: i16,
1927 }
1928
1929 impl PacketId for ClientboundSpawnEntity {
1930 fn packet_id(_ver: u32) -> u8 {
1931 0x0E
1932 }
1933 }
1934
1935 impl Encode for ClientboundSpawnEntity {
1936 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1937 dst.put_i32(self.entity_id);
1938 dst.put_i8(self.entity_type);
1939 dst.put_i32(self.x);
1940 dst.put_i32(self.y);
1941 dst.put_i32(self.z);
1942 dst.put_i8(self.yaw);
1943 dst.put_i8(self.pitch);
1944 dst.put_i8(self.head_pitch);
1945 dst.put_i16(self.velocity_x);
1946 dst.put_i16(self.velocity_y);
1947 dst.put_i16(self.velocity_z);
1948 Ok(())
1949 }
1950 }
1951
1952 impl Decode for ClientboundSpawnEntity {
1953 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1954 need(src, 4 + 1 + 4 + 4 + 4 + 1 + 1 + 1 + 2 + 2 + 2)?;
1955 Ok(Self {
1956 entity_id: src.get_i32(),
1957 entity_type: src.get_i8(),
1958 x: src.get_i32(),
1959 y: src.get_i32(),
1960 z: src.get_i32(),
1961 yaw: src.get_i8(),
1962 pitch: src.get_i8(),
1963 head_pitch: src.get_i8(),
1964 velocity_x: src.get_i16(),
1965 velocity_y: src.get_i16(),
1966 velocity_z: src.get_i16(),
1967 })
1968 }
1969 }
1970
1971 #[derive(Debug, Clone, PartialEq)]
1974 pub struct ClientboundSetExperience {
1975 pub experience_bar: f32,
1976 pub level: i16,
1977 pub total_experience: i16,
1978 }
1979
1980 impl PacketId for ClientboundSetExperience {
1981 fn packet_id(_ver: u32) -> u8 {
1982 0x1F
1983 }
1984 }
1985
1986 impl Encode for ClientboundSetExperience {
1987 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
1988 dst.put_f32(self.experience_bar);
1989 dst.put_i16(self.level);
1990 dst.put_i16(self.total_experience);
1991 Ok(())
1992 }
1993 }
1994
1995 impl Decode for ClientboundSetExperience {
1996 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
1997 need(src, 4 + 2 + 2)?;
1998 Ok(Self {
1999 experience_bar: src.get_f32(),
2000 level: src.get_i16(),
2001 total_experience: src.get_i16(),
2002 })
2003 }
2004 }
2005
2006 #[derive(Debug, Clone, PartialEq)]
2009 pub struct ClientboundBlockUpdate {
2010 pub x: i32,
2011 pub y: i8,
2012 pub z: i32,
2013 pub block_id: i32,
2014 pub block_metadata: i8,
2015 }
2016
2017 impl PacketId for ClientboundBlockUpdate {
2018 fn packet_id(_ver: u32) -> u8 {
2019 0x23
2020 }
2021 }
2022
2023 impl Encode for ClientboundBlockUpdate {
2024 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2025 dst.put_i32(self.x);
2026 dst.put_i8(self.y);
2027 dst.put_i32(self.z);
2028 VarInt(self.block_id).encode(dst)?;
2029 dst.put_i8(self.block_metadata);
2030 Ok(())
2031 }
2032 }
2033
2034 impl Decode for ClientboundBlockUpdate {
2035 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2036 need(src, 4 + 1 + 4)?;
2037 Ok(Self {
2038 x: src.get_i32(),
2039 y: src.get_i8(),
2040 z: src.get_i32(),
2041 block_id: VarInt::decode(src)?.0,
2042 block_metadata: src.get_i8(),
2043 })
2044 }
2045 }
2046
2047 #[derive(Debug, Clone, PartialEq)]
2050 pub struct ClientboundSetHeldItem {
2051 pub slot: u8,
2052 }
2053
2054 impl PacketId for ClientboundSetHeldItem {
2055 fn packet_id(_ver: u32) -> u8 {
2056 0x09
2057 }
2058 }
2059
2060 impl Encode for ClientboundSetHeldItem {
2061 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2062 dst.put_u8(self.slot);
2063 Ok(())
2064 }
2065 }
2066
2067 impl Decode for ClientboundSetHeldItem {
2068 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2069 need(src, 1)?;
2070 Ok(Self { slot: src.get_u8() })
2071 }
2072 }
2073
2074 #[derive(Debug, Clone, PartialEq)]
2077 pub struct ClientboundSound {
2078 pub sound_name: String,
2079 pub x: i32,
2080 pub y: i32,
2081 pub z: i32,
2082 pub volume: f32,
2083 pub pitch: u8,
2084 }
2085
2086 impl PacketId for ClientboundSound {
2087 fn packet_id(_ver: u32) -> u8 {
2088 0x29
2089 }
2090 }
2091
2092 impl Encode for ClientboundSound {
2093 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2094 encode_str(&self.sound_name, dst)?;
2095 dst.put_i32(self.x);
2096 dst.put_i32(self.y);
2097 dst.put_i32(self.z);
2098 dst.put_f32(self.volume);
2099 dst.put_u8(self.pitch);
2100 Ok(())
2101 }
2102 }
2103
2104 impl Decode for ClientboundSound {
2105 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2106 let sound_name = decode_str(src, "ClientboundSound sound_name")?;
2107 need(src, 4 + 4 + 4 + 4 + 1)?;
2108 Ok(Self {
2109 sound_name,
2110 x: src.get_i32(),
2111 y: src.get_i32(),
2112 z: src.get_i32(),
2113 volume: src.get_f32(),
2114 pitch: src.get_u8(),
2115 })
2116 }
2117 }
2118
2119 #[derive(Debug, Clone, PartialEq)]
2122 pub struct ClientboundPlayerAbilities {
2123 pub flags: u8,
2124 pub flying_speed: f32,
2125 pub field_of_view_modifier: f32,
2126 }
2127
2128 impl PacketId for ClientboundPlayerAbilities {
2129 fn packet_id(_ver: u32) -> u8 {
2130 0x39
2131 }
2132 }
2133
2134 impl Encode for ClientboundPlayerAbilities {
2135 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2136 dst.put_u8(self.flags);
2137 dst.put_f32(self.flying_speed);
2138 dst.put_f32(self.field_of_view_modifier);
2139 Ok(())
2140 }
2141 }
2142
2143 impl Decode for ClientboundPlayerAbilities {
2144 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2145 need(src, 1 + 4 + 4)?;
2146 Ok(Self {
2147 flags: src.get_u8(),
2148 flying_speed: src.get_f32(),
2149 field_of_view_modifier: src.get_f32(),
2150 })
2151 }
2152 }
2153
2154 #[derive(Debug, Clone, PartialEq)]
2157 pub struct ClientboundContainerSetContent {
2158 pub window_id: u8,
2159 pub slots: Vec<LegacySlot>,
2160 pub carried_item: LegacySlot,
2161 }
2162
2163 impl PacketId for ClientboundContainerSetContent {
2164 fn packet_id(_ver: u32) -> u8 {
2165 0x30
2166 }
2167 }
2168
2169 impl Encode for ClientboundContainerSetContent {
2170 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2171 dst.put_u8(self.window_id);
2172 dst.put_i16(self.slots.len() as i16);
2173 for slot in &self.slots {
2174 slot.encode(dst)?;
2175 }
2176 self.carried_item.encode(dst)?;
2177 Ok(())
2178 }
2179 }
2180
2181 impl Decode for ClientboundContainerSetContent {
2182 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2183 need(src, 1 + 2)?;
2184 let window_id = src.get_u8();
2185 let count = src.get_i16() as usize;
2186 let mut slots = Vec::with_capacity(count);
2187 for _ in 0..count {
2188 slots.push(LegacySlot::decode(src)?);
2189 }
2190 let carried_item = LegacySlot::decode(src)?;
2191 Ok(Self {
2192 window_id,
2193 slots,
2194 carried_item,
2195 })
2196 }
2197 }
2198
2199 #[derive(Debug, Clone, PartialEq)]
2202 pub struct ClientboundContainerSetSlot {
2203 pub window_id: i8,
2204 pub slot: i16,
2205 pub slot_data: LegacySlot,
2206 }
2207
2208 impl PacketId for ClientboundContainerSetSlot {
2209 fn packet_id(_ver: u32) -> u8 {
2210 0x2F
2211 }
2212 }
2213
2214 impl Encode for ClientboundContainerSetSlot {
2215 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2216 dst.put_i8(self.window_id);
2217 dst.put_i16(self.slot);
2218 self.slot_data.encode(dst)?;
2219 Ok(())
2220 }
2221 }
2222
2223 impl Decode for ClientboundContainerSetSlot {
2224 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2225 need(src, 1 + 2)?;
2226 let window_id = src.get_i8();
2227 let slot = src.get_i16();
2228 let slot_data = LegacySlot::decode(src)?;
2229 Ok(Self {
2230 window_id,
2231 slot,
2232 slot_data,
2233 })
2234 }
2235 }
2236
2237 raw_packet!(ClientboundMapItemData, 0x34);
2238 raw_packet!(ClientboundBlockEntityData, 0x35);
2239 raw_packet!(ClientboundAwardStats, 0x37);
2240 raw_packet!(ClientboundCommandSuggestions, 0x3A);
2241 raw_packet!(ClientboundSetScoreboardObjective, 0x3B);
2242 raw_packet!(ClientboundResetScore, 0x3B);
2243 raw_packet!(ClientboundSetScoreboardScore, 0x3C);
2244 raw_packet!(ClientboundChangeDifficulty, 0x41);
2245 raw_packet!(ClientboundPlayerCombatEnd, 0x42);
2246 raw_packet!(ClientboundPlayerCombatEnter, 0x42);
2247 raw_packet!(ClientboundPlayerCombatKill, 0x42);
2248
2249 #[derive(Debug, Clone, PartialEq)]
2252 pub struct ClientboundOpenSignEditor {
2253 pub x: i32,
2254 pub y: i32,
2255 pub z: i32,
2256 }
2257
2258 impl PacketId for ClientboundOpenSignEditor {
2259 fn packet_id(_ver: u32) -> u8 {
2260 0x36
2261 }
2262 }
2263
2264 impl Encode for ClientboundOpenSignEditor {
2265 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2266 dst.put_i32(self.x);
2267 dst.put_i32(self.y);
2268 dst.put_i32(self.z);
2269 Ok(())
2270 }
2271 }
2272
2273 impl Decode for ClientboundOpenSignEditor {
2274 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2275 need(src, 4 + 4 + 4)?;
2276 Ok(Self {
2277 x: src.get_i32(),
2278 y: src.get_i32(),
2279 z: src.get_i32(),
2280 })
2281 }
2282 }
2283
2284 #[derive(Debug, Clone, PartialEq)]
2287 pub struct ClientboundPlayerInfoUpdate {
2288 pub action: i8,
2289 pub data: Vec<u8>,
2290 }
2291
2292 impl PacketId for ClientboundPlayerInfoUpdate {
2293 fn packet_id(_ver: u32) -> u8 {
2294 0x38
2295 }
2296 }
2297
2298 impl Encode for ClientboundPlayerInfoUpdate {
2299 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2300 dst.put_i8(self.action);
2301 dst.extend_from_slice(&self.data);
2302 Ok(())
2303 }
2304 }
2305
2306 impl Decode for ClientboundPlayerInfoUpdate {
2307 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2308 need(src, 1)?;
2309 let action = src.get_i8();
2310 let data = src.to_vec();
2311 Ok(Self { action, data })
2312 }
2313 }
2314
2315 #[derive(Debug, Clone, PartialEq)]
2318 pub struct ClientboundTabList {
2319 pub header: String,
2320 pub footer: String,
2321 }
2322
2323 impl PacketId for ClientboundTabList {
2324 fn packet_id(_ver: u32) -> u8 {
2325 0x47
2326 }
2327 }
2328
2329 impl Encode for ClientboundTabList {
2330 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2331 encode_str(&self.header, dst)?;
2332 encode_str(&self.footer, dst)?;
2333 Ok(())
2334 }
2335 }
2336
2337 impl Decode for ClientboundTabList {
2338 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2339 let header = decode_str(src, "ClientboundTabList header")?;
2340 let footer = decode_str(src, "ClientboundTabList footer")?;
2341 Ok(Self { header, footer })
2342 }
2343 }
2344
2345 #[derive(Debug, Clone, PartialEq)]
2348 pub struct ClientboundResourcePackPush {
2349 pub url: String,
2350 pub hash: String,
2351 }
2352
2353 impl PacketId for ClientboundResourcePackPush {
2354 fn packet_id(_ver: u32) -> u8 {
2355 0x48
2356 }
2357 }
2358
2359 impl Encode for ClientboundResourcePackPush {
2360 fn encode(&self, dst: &mut BytesMut) -> Result<(), ProtocolError> {
2361 encode_str(&self.url, dst)?;
2362 encode_str(&self.hash, dst)?;
2363 Ok(())
2364 }
2365 }
2366
2367 impl Decode for ClientboundResourcePackPush {
2368 fn decode(src: &mut Bytes) -> Result<Self, ProtocolError> {
2369 let url = decode_str(src, "ClientboundResourcePackPush url")?;
2370 let hash = decode_str(src, "ClientboundResourcePackPush hash")?;
2371 Ok(Self { url, hash })
2372 }
2373 }
2374
2375 raw_packet!(ServerboundMovePlayerStatusOnly, 0x03);
2376 raw_packet!(ServerboundPlayerAction, 0x07);
2377 raw_packet!(ServerboundPlayerBlockPlacement, 0x08);
2378 raw_packet!(ServerboundHeldItemChange, 0x09);
2379 raw_packet!(ServerboundAnimation, 0x0A);
2380 raw_packet!(ServerboundEntityAction, 0x0B);
2381 raw_packet!(ServerboundSteerVehicle, 0x0C);
2382 raw_packet!(ServerboundCloseWindow, 0x0D);
2383 raw_packet!(ServerboundClickWindow, 0x0E);
2384 raw_packet!(ServerboundConfirmTransaction, 0x0F);
2385 raw_packet!(ServerboundCreativeInventoryAction, 0x10);
2386 raw_packet!(ServerboundEnchantItem, 0x11);
2387 raw_packet!(ServerboundClickWindowButton, 0x11);
2388 raw_packet!(ServerboundUpdateSign, 0x12);
2389 raw_packet!(ServerboundPlayerAbilities, 0x13);
2390 raw_packet!(ServerboundCommandSuggestion, 0x14);
2391 raw_packet!(ServerboundClientSettings, 0x15);
2392 raw_packet!(ServerboundClientStatus, 0x16);
2393 raw_packet!(ServerboundResourcePackStatus, 0x19);
2394}
2395
2396#[cfg(test)]
2397mod tests {
2398 use super::*;
2399
2400 macro_rules! roundtrip {
2401 ($T:ty, $val:expr) => {{
2402 let v = $val;
2403 let mut buf = BytesMut::new();
2404 v.encode(&mut buf).unwrap();
2405 let mut b = buf.freeze();
2406 assert_eq!(<$T>::decode(&mut b).unwrap(), v);
2407 }};
2408 }
2409
2410 #[test]
2411 fn keepalive_roundtrip() {
2412 roundtrip!(
2413 ClientboundKeepAlive,
2414 ClientboundKeepAlive {
2415 keep_alive_id: VarInt(42)
2416 }
2417 );
2418 roundtrip!(
2419 ServerboundKeepAlive,
2420 ServerboundKeepAlive {
2421 keep_alive_id: VarInt(42)
2422 }
2423 );
2424 }
2425
2426 #[test]
2427 fn join_game_roundtrip() {
2428 roundtrip!(
2429 ClientboundJoinGame,
2430 ClientboundJoinGame {
2431 entity_id: 1,
2432 game_mode: 0,
2433 dimension: 0,
2434 difficulty: 1,
2435 max_players: 20,
2436 level_type: "default".to_string(),
2437 reduced_debug_info: false,
2438 }
2439 );
2440 }
2441
2442 #[test]
2443 fn chat_roundtrip() {
2444 roundtrip!(
2445 ClientboundChatMessage,
2446 ClientboundChatMessage {
2447 json_message: r#"{"text":"hi"}"#.to_string(),
2448 position: 0,
2449 }
2450 );
2451 roundtrip!(
2452 ServerboundChatMessage,
2453 ServerboundChatMessage {
2454 message: "hello".to_string()
2455 }
2456 );
2457 }
2458
2459 #[test]
2460 fn respawn_roundtrip() {
2461 roundtrip!(
2462 ClientboundRespawn,
2463 ClientboundRespawn {
2464 dimension: -1,
2465 difficulty: 2,
2466 game_mode: 0,
2467 level_type: "default".to_string(),
2468 }
2469 );
2470 }
2471
2472 #[test]
2473 fn player_position_roundtrip() {
2474 roundtrip!(
2475 ClientboundPlayerPosition,
2476 ClientboundPlayerPosition {
2477 x: 10.0,
2478 head_y: 66.62,
2479 z: -5.0,
2480 yaw: 0.0,
2481 pitch: 0.0,
2482 flags: 0,
2483 }
2484 );
2485 }
2486
2487 #[test]
2488 fn disconnect_roundtrip() {
2489 roundtrip!(
2490 ClientboundDisconnect,
2491 ClientboundDisconnect {
2492 reason: r#"{"text":"bye"}"#.to_string(),
2493 }
2494 );
2495 }
2496
2497 #[test]
2498 fn movement_roundtrip() {
2499 roundtrip!(
2500 ServerboundMovePlayerPos,
2501 ServerboundMovePlayerPos {
2502 x: 5.0,
2503 feet_y: 64.0,
2504 z: -2.0,
2505 on_ground: true,
2506 }
2507 );
2508 roundtrip!(
2509 ServerboundMovePlayerRot,
2510 ServerboundMovePlayerRot {
2511 yaw: 90.0,
2512 pitch: -10.0,
2513 on_ground: true,
2514 }
2515 );
2516 roundtrip!(
2517 ServerboundMovePlayerPosRot,
2518 ServerboundMovePlayerPosRot {
2519 x: 1.0,
2520 feet_y: 65.0,
2521 z: 2.0,
2522 yaw: 180.0,
2523 pitch: 45.0,
2524 on_ground: false,
2525 }
2526 );
2527 }
2528
2529 #[test]
2530 fn interact_roundtrip() {
2531 roundtrip!(
2532 ServerboundInteract,
2533 ServerboundInteract {
2534 entity_id: VarInt(1),
2535 action: InteractAction::Attack,
2536 }
2537 );
2538 roundtrip!(
2539 ServerboundInteract,
2540 ServerboundInteract {
2541 entity_id: VarInt(2),
2542 action: InteractAction::Interact,
2543 }
2544 );
2545 roundtrip!(
2546 ServerboundInteract,
2547 ServerboundInteract {
2548 entity_id: VarInt(3),
2549 action: InteractAction::InteractAt {
2550 target_x: 0.5,
2551 target_y: 1.0,
2552 target_z: 0.5
2553 },
2554 }
2555 );
2556 }
2557
2558 #[test]
2559 fn plugin_message_roundtrip() {
2560 roundtrip!(
2561 ClientboundPluginMessage,
2562 ClientboundPluginMessage {
2563 channel: "MC|Brand".to_string(),
2564 data: b"vanilla".to_vec(),
2565 }
2566 );
2567 roundtrip!(
2568 ServerboundPluginMessage,
2569 ServerboundPluginMessage {
2570 channel: "MC|Brand".to_string(),
2571 data: b"client".to_vec(),
2572 }
2573 );
2574 }
2575
2576 #[test]
2577 fn packet_ids() {
2578 assert_eq!(ClientboundKeepAlive::packet_id(5), 0x00);
2579 assert_eq!(ClientboundJoinGame::packet_id(5), 0x01);
2580 assert_eq!(ClientboundChatMessage::packet_id(5), 0x02);
2581 assert_eq!(ClientboundRespawn::packet_id(5), 0x07);
2582 assert_eq!(ClientboundPlayerPosition::packet_id(5), 0x08);
2583 assert_eq!(ClientboundDisconnect::packet_id(5), 0x40);
2584 assert_eq!(ClientboundPluginMessage::packet_id(5), 0x3F);
2585 assert_eq!(ServerboundKeepAlive::packet_id(5), 0x00);
2586 assert_eq!(ServerboundChatMessage::packet_id(5), 0x01);
2587 assert_eq!(ServerboundInteract::packet_id(5), 0x02);
2588 assert_eq!(ServerboundMovePlayerPos::packet_id(5), 0x04);
2589 assert_eq!(ServerboundMovePlayerRot::packet_id(5), 0x05);
2590 assert_eq!(ServerboundMovePlayerPosRot::packet_id(5), 0x06);
2591 assert_eq!(ServerboundPluginMessage::packet_id(5), 0x17);
2592 }
2593}