diff --git a/msg_tool_xp3data/crypt.json b/msg_tool_xp3data/crypt.json index a575655..f81088b 100644 --- a/msg_tool_xp3data/crypt.json +++ b/msg_tool_xp3data/crypt.json @@ -2259,6 +2259,10 @@ "ControlBlockName": "yomibito.bin", "Title": "黄泉ビト知ラズ~甘い雌蕊の性徴詩~" }, + "Yotsunoha": { + "$type": "HaikuoCrypt", + "Title": "よつのは | 四叶草" + }, "your diary + H": { "$type": "SourireCrypt" }, diff --git a/src/scripts/kirikiri/archive/xp3/crypt/mod.rs b/src/scripts/kirikiri/archive/xp3/crypt/mod.rs index d71628a..6bc5aa6 100644 --- a/src/scripts/kirikiri/archive/xp3/crypt/mod.rs +++ b/src/scripts/kirikiri/archive/xp3/crypt/mod.rs @@ -175,6 +175,7 @@ enum CryptType { AkabeiCrypt { seed: u32, }, + HaikuoCrypt, } #[derive(Clone, Debug, Deserialize)] @@ -274,6 +275,7 @@ impl Schema { CryptType::SourireCrypt => Box::new(SourireCrypt::new(self.base.clone())), CryptType::HibikiCrypt => Box::new(HibikiCrypt::new(self.base.clone())), CryptType::AkabeiCrypt { seed } => Box::new(AkabeiCrypt::new(self.base.clone(), *seed)), + CryptType::HaikuoCrypt => Box::new(HaikuoCrypt::new(self.base.clone())), }) } } @@ -1148,6 +1150,20 @@ impl Read for AkabeiCryptReader { } } +seek_crypt_filehash_key_impl!(HaikuoCrypt, HaikuoCryptReader); + +impl Read for HaikuoCryptReader { + fn read(&mut self, buf: &mut [u8]) -> std::io::Result { + let readed = self.inner.read(buf)?; + let key = (self.key ^ (self.key >> 8)) as u8; + for t in (&mut buf[..readed]).iter_mut() { + *t ^= key; + } + self.pos += readed as u64; + Ok(readed) + } +} + #[test] fn test_deserialize_crypt() { for (key, schema) in CRYPT_SCHEMA.iter() {