1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use crate::network::*;
use crate::packet::*;
use basin2_lib::result::*;
use bytes::BytesMut;

#[derive(PartialEq, Clone, Debug)]
pub struct MapItemDataPacket {
    pub mapId: i32,
    pub scale: u8,
    pub trackingPosition: bool,
    pub locked: bool,
    pub decorations: Vec<MapDecoration>,
    pub startX: u8,
    pub startY: u8,
    pub width: u8,
    pub height: u8,
    pub mapColors: Vec<u8>,
}

impl CodablePacket for MapItemDataPacket {
    fn encode(self, buf: &mut BytesMut) {
        buf.set_mc_var_int(self.mapId);
        buf.set_mc_u8(self.scale);
        buf.set_mc_bool(self.trackingPosition);
        buf.set_mc_bool(self.locked);
        buf.set_mc_var_int(self.decorations.len() as i32);
        for decoration in self.decorations {
            buf.set_mc_var_int(decoration.decoration_type as i32);
            buf.set_mc_u8(decoration.x);
            buf.set_mc_u8(decoration.y);
            buf.set_mc_u8(decoration.rot & 15);
            match decoration.component {
                Some(component) => {
                    buf.set_mc_bool(true);
                    buf.set_mc_chat_component(component);
                }
                None => {
                    buf.set_mc_bool(false);
                }
            }
        }
        buf.set_mc_u8(self.width);
        if self.width > 0 {
            buf.set_mc_u8(self.height);
            buf.set_mc_u8(self.startX);
            buf.set_mc_u8(self.startY);
            buf.set_mc_byte_array(self.mapColors);
        }
    }

    fn decode(buf: &mut BytesMut) -> Result<Self>
    where
        Self: Sized,
    {
        let mapId = buf.get_mc_var_int()?;
        let scale = buf.get_mc_u8()?;
        let trackingPosition = buf.get_mc_bool()?;
        let locked = buf.get_mc_bool()?;
        let decorations_count = buf.get_mc_var_int()?;
        let mut decorations: Vec<MapDecoration> = vec![];
        for _ in 0..decorations_count {
            decorations.push(MapDecoration {
                decoration_type: buf.get_mc_enum()?,
                x: buf.get_mc_u8()?,
                y: buf.get_mc_u8()?,
                rot: buf.get_mc_u8()? & 15,
                component: match buf.get_mc_bool()? {
                    true => Some(buf.get_mc_chat_component()?),
                    false => None,
                },
            });
        }
        let width = buf.get_mc_u8()?;
        let (height, startX, startY, mapColors) = match width {
            x if x > 0 => (
                buf.get_mc_u8()?,
                buf.get_mc_u8()?,
                buf.get_mc_u8()?,
                buf.get_mc_byte_array_bounded(2048)?,
            ),
            _ => (0, 0, 0, vec![]),
        };
        return Ok(MapItemDataPacket {
            mapId,
            scale,
            trackingPosition,
            locked,
            decorations,
            startX,
            startY,
            width,
            height,
            mapColors,
        });
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::packet::test::*;

    #[test]
    fn test_cycle() -> Result<()> {
        cycle(MapItemDataPacket {
            mapId: 234,
            scale: 8,
            trackingPosition: true,
            locked: false,
            decorations: vec![MapDecoration {
                decoration_type: MapDecorationType::BannerMagenta,
                x: 23,
                y: 19,
                rot: 1,
                component: Some(ChatComponent::from("test".to_string())),
            }],
            startX: 12,
            startY: 25,
            width: 90,
            height: 90,
            mapColors: vec![12, 96],
        })
    }
}