mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-07-08 01:31:53 +08:00
Add StripeCrypt (untested)
This commit is contained in:
@@ -1974,6 +1974,11 @@
|
|||||||
"$type": "HashCrypt",
|
"$type": "HashCrypt",
|
||||||
"Title": "双性の姫君 ~ふたなり姉妹と魔王の求愛~"
|
"Title": "双性の姫君 ~ふたなり姉妹と魔王の求愛~"
|
||||||
},
|
},
|
||||||
|
"Specialite!": {
|
||||||
|
"$type": "StripeCrypt",
|
||||||
|
"Key": 175,
|
||||||
|
"Title": "すぺしゃりて!"
|
||||||
|
},
|
||||||
"Suiheisen made Nan Mile?": {
|
"Suiheisen made Nan Mile?": {
|
||||||
"$type": "CxEncryption",
|
"$type": "CxEncryption",
|
||||||
"Mask": 610,
|
"Mask": 610,
|
||||||
|
|||||||
@@ -176,6 +176,10 @@ enum CryptType {
|
|||||||
seed: u32,
|
seed: u32,
|
||||||
},
|
},
|
||||||
HaikuoCrypt,
|
HaikuoCrypt,
|
||||||
|
#[serde(rename_all = "PascalCase")]
|
||||||
|
StripeCrypt {
|
||||||
|
key: u8,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize)]
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
@@ -276,6 +280,7 @@ impl Schema {
|
|||||||
CryptType::HibikiCrypt => Box::new(HibikiCrypt::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::AkabeiCrypt { seed } => Box::new(AkabeiCrypt::new(self.base.clone(), *seed)),
|
||||||
CryptType::HaikuoCrypt => Box::new(HaikuoCrypt::new(self.base.clone())),
|
CryptType::HaikuoCrypt => Box::new(HaikuoCrypt::new(self.base.clone())),
|
||||||
|
CryptType::StripeCrypt { key } => Box::new(StripeCrypt::new(self.base.clone(), *key)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -604,45 +609,54 @@ impl<R: Read> Read for HashCryptReader<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
macro_rules! seek_crypt_key_base_impl {
|
||||||
pub struct XorCrypt {
|
($crypt:ident, $reader:ident, $typ:ty) => {
|
||||||
base: BaseSchema,
|
#[derive(Debug)]
|
||||||
key: u8,
|
pub struct $crypt {
|
||||||
|
base: BaseSchema,
|
||||||
|
key: $typ,
|
||||||
|
}
|
||||||
|
impl $crypt {
|
||||||
|
pub fn new(base: BaseSchema, key: $typ) -> Self {
|
||||||
|
Self { base, key }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Crypt for $crypt {
|
||||||
|
base_schema_impl!();
|
||||||
|
fn decrypt_supported(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
fn decrypt_seek_supported(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
fn decrypt<'a>(
|
||||||
|
&self,
|
||||||
|
_entry: &Xp3Entry,
|
||||||
|
cur_seg: &Segment,
|
||||||
|
stream: Box<dyn Read + 'a>,
|
||||||
|
) -> Result<Box<dyn ReadDebug + 'a>> {
|
||||||
|
Ok(Box::new($reader::new(stream, cur_seg, self.key)))
|
||||||
|
}
|
||||||
|
fn decrypt_with_seek<'a>(
|
||||||
|
&self,
|
||||||
|
_entry: &Xp3Entry,
|
||||||
|
cur_seg: &Segment,
|
||||||
|
stream: Box<dyn ReadSeek + 'a>,
|
||||||
|
) -> Result<Box<dyn ReadSeek + 'a>> {
|
||||||
|
Ok(Box::new($reader::new(stream, cur_seg, self.key)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XorCrypt {
|
macro_rules! seek_crypt_key_impl {
|
||||||
pub fn new(base: BaseSchema, key: u8) -> Self {
|
($crypt:ident, $reader:ident<$t:ident>, $typ:ty) => {
|
||||||
Self { base, key }
|
seek_crypt_key_base_impl!($crypt, $reader, $typ);
|
||||||
}
|
seek_reader_key_impl!($reader<$t>, $typ);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Crypt for XorCrypt {
|
seek_crypt_key_impl!(XorCrypt, XorCryptReader<T>, u8);
|
||||||
base_schema_impl!();
|
|
||||||
fn decrypt_supported(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
fn decrypt_seek_supported(&self) -> bool {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
fn decrypt<'a>(
|
|
||||||
&self,
|
|
||||||
_entry: &Xp3Entry,
|
|
||||||
cur_seg: &Segment,
|
|
||||||
stream: Box<dyn Read + 'a>,
|
|
||||||
) -> Result<Box<dyn ReadDebug + 'a>> {
|
|
||||||
Ok(Box::new(XorCryptReader::new(stream, cur_seg, self.key)))
|
|
||||||
}
|
|
||||||
fn decrypt_with_seek<'a>(
|
|
||||||
&self,
|
|
||||||
_entry: &Xp3Entry,
|
|
||||||
cur_seg: &Segment,
|
|
||||||
stream: Box<dyn ReadSeek + 'a>,
|
|
||||||
) -> Result<Box<dyn ReadSeek + 'a>> {
|
|
||||||
Ok(Box::new(XorCryptReader::new(stream, cur_seg, self.key)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
seek_reader_key_impl!(XorCryptReader<T>, u8);
|
|
||||||
|
|
||||||
impl<R: Read> Read for XorCryptReader<R> {
|
impl<R: Read> Read for XorCryptReader<R> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
@@ -1164,6 +1178,20 @@ impl<R: Read> Read for HaikuoCryptReader<R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
seek_crypt_key_impl!(StripeCrypt, StripeCryptReader<T>, u8);
|
||||||
|
|
||||||
|
impl<R: Read> Read for StripeCryptReader<R> {
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
|
let readed = self.inner.read(buf)?;
|
||||||
|
for t in (&mut buf[..readed]).iter_mut() {
|
||||||
|
*t ^= self.key;
|
||||||
|
w!(*t += 1);
|
||||||
|
}
|
||||||
|
self.pos += readed as u64;
|
||||||
|
Ok(readed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_deserialize_crypt() {
|
fn test_deserialize_crypt() {
|
||||||
for (key, schema) in CRYPT_SCHEMA.iter() {
|
for (key, schema) in CRYPT_SCHEMA.iter() {
|
||||||
|
|||||||
Reference in New Issue
Block a user