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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
use crate::network::*; use crate::packet::*; use basin2_lib::result::*; use bytes::BytesMut; #[derive(PartialEq, Clone, Debug)] pub struct SetStructureBlockPacket { pub pos: BlockPos, pub updateType: StructureBlockEntityUpdateType, pub mode: StructureMode, pub name: String, pub offset: BlockPos, pub size: BlockPos, pub mirror: Mirror, pub rotation: Rotation, pub data: String, pub ignoreEntities: bool, pub showAir: bool, pub showBoundingBox: bool, pub integrity: f32, pub seed: i64, } fn clamp(value: i8, from: i32, to: i32) -> i32 { let value = value as i32; return if value < from { from } else if value > to { to } else { value }; } impl CodablePacket for SetStructureBlockPacket { fn encode(self, buf: &mut BytesMut) { buf.set_mc_block_pos(self.pos); buf.set_mc_var_int(self.updateType as i32); buf.set_mc_var_int(self.mode as i32); buf.set_mc_string(self.name); buf.set_mc_i8(self.offset.x as i8); buf.set_mc_i8(self.offset.y as i8); buf.set_mc_i8(self.offset.z as i8); buf.set_mc_i8(self.size.x as i8); buf.set_mc_i8(self.size.y as i8); buf.set_mc_i8(self.size.z as i8); buf.set_mc_var_int(self.mirror as i32); buf.set_mc_var_int(self.rotation as i32); buf.set_mc_string(self.data); buf.set_mc_f32(self.integrity); buf.set_mc_var_long(self.seed); let mut flags: u8 = 0; if self.ignoreEntities { flags |= 1; } if self.showAir { flags |= 2; } if self.showBoundingBox { flags |= 4; } buf.set_mc_u8(flags); } fn decode(buf: &mut BytesMut) -> Result<Self> where Self: Sized, { let pos = buf.get_mc_block_pos()?; let updateType: StructureBlockEntityUpdateType = buf.get_mc_enum()?; let mode: StructureMode = buf.get_mc_enum()?; let name = buf.get_mc_string(32767)?; let offset = BlockPos { x: clamp(buf.get_mc_i8()?, -32, 32), y: clamp(buf.get_mc_i8()?, -32, 32), z: clamp(buf.get_mc_i8()?, -32, 32), }; let size = BlockPos { x: clamp(buf.get_mc_i8()?, -32, 32), y: clamp(buf.get_mc_i8()?, -32, 32), z: clamp(buf.get_mc_i8()?, -32, 32), }; let mirror: Mirror = buf.get_mc_enum()?; let rotation: Rotation = buf.get_mc_enum()?; let data = buf.get_mc_string(12)?; let integrity = buf.get_mc_f32()?; let integrity = if integrity < 0.0 { 0.0 } else if integrity > 1.0 { 1.0 } else { integrity }; let seed = buf.get_mc_var_long()?; let flags = buf.get_mc_u8()?; let ignoreEntities = (flags & 1) > 0; let showAir = (flags & 2) > 0; let showBoundingBox = (flags & 4) > 0; return Ok(SetStructureBlockPacket { pos, updateType, mode, name, offset, size, mirror, rotation, data, ignoreEntities, showAir, showBoundingBox, integrity, seed, }); } } #[cfg(test)] mod tests { use super::*; use crate::packet::test::*; #[test] fn test_cycle() -> Result<()> { cycle(SetStructureBlockPacket { pos: BlockPos { x: -10, y: -20, z: -30, }, updateType: StructureBlockEntityUpdateType::UpdateData, mode: StructureMode::Save, name: "structure name".to_string(), offset: BlockPos { x: -1, y: 5, z: 2 }, size: BlockPos { x: 3, y: 3, z: 3 }, mirror: Mirror::LeftRight, rotation: Rotation::Clockwise90, data: "some data".to_string(), ignoreEntities: true, showAir: false, showBoundingBox: true, integrity: 1.0, seed: 6724562345, }) } }