760 comment lines become 262; the code is unchanged. One doc said the opposite of its code: corpse_look is None when either BYTES word is missing, not neither. The ObjectFields doc had drifted onto CorpseLook and is back on its struct. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
37 lines
1.2 KiB
Rust
37 lines
1.2 KiB
Rust
//! Tutorial wire: one inbound bank of bits and the client's three tutorial sends. The 1.12
|
|
//! client sizes its banks from every remaining byte of the packet; vmangos sends 32 bytes.
|
|
|
|
use std::io::{self, Read};
|
|
|
|
/// `SMSG_TUTORIAL_FLAGS` (handler `0x4b5700`): bit `id` is `bytes[id >> 3] & (1 << (id & 7))`.
|
|
#[derive(Clone, Debug, PartialEq, Eq, Default)]
|
|
pub struct TutorialFlags {
|
|
pub bytes: Vec<u8>,
|
|
}
|
|
|
|
pub(super) fn read_tutorial_flags(r: &mut impl Read) -> io::Result<TutorialFlags> {
|
|
let mut bytes = Vec::new();
|
|
r.read_to_end(&mut bytes)?;
|
|
Ok(TutorialFlags { bytes })
|
|
}
|
|
|
|
/// `CMSG_TUTORIAL_FLAG` (`0x4b54c0`): the 0-based id as a `u32`.
|
|
pub fn tutorial_flag(id: u32) -> Vec<u8> {
|
|
id.to_le_bytes().to_vec()
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn the_bank_is_every_remaining_byte_and_the_flag_is_one_dword() {
|
|
let body = [0x01u8, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF];
|
|
let f = read_tutorial_flags(&mut body.as_slice()).unwrap();
|
|
assert_eq!(f.bytes, body.to_vec());
|
|
let f = read_tutorial_flags(&mut [].as_slice()).unwrap();
|
|
assert!(f.bytes.is_empty(), "an empty body is an empty bank");
|
|
assert_eq!(tutorial_flag(41), vec![41, 0, 0, 0]);
|
|
}
|
|
}
|