Add HashCrypt support (tested game: https://vndb.org/v16201 )

This commit is contained in:
2026-04-06 15:01:15 +08:00
parent d9e640d437
commit 01216d49b1
2 changed files with 500 additions and 2 deletions

View File

@@ -1,13 +1,420 @@
{
"25c -Sono Hako wa Shoujo no Himei o Morasanai-": {
"$type": "HashCrypt",
"Title": "25c -その箱は少女の悲鳴を漏らさない-"
},
"Aisai Injoku Settai": {
"$type": "HashCrypt",
"Title": "愛妻淫辱接待~借金のかたに妻の調教を命じられた夫~"
},
"Ama Koi Syrups": {
"$type": "HashCrypt",
"Title": "あま恋シロップス ~恥じらう恋心でシたくなる甘神様の恋祭り~ | 甘神大人的糖浆恋祭"
},
"Anata no Milk Kudasai na": {
"$type": "HashCrypt",
"Title": "あなたの精液くださいな ~私とボクとどっちがお好み?~"
},
"Anedori": {
"$type": "HashCrypt",
"Title": "姉撮 ~堕ちていくお姉ちゃんを助けられない僕~"
},
"Baaba to Mama to no Choujuku Oyakodon": {
"$type": "HashCrypt",
"Title": "ばぁばとママとの超熟母娘丼 ~3世代での家庭内エッチ~ | 爱你深至夏海蔚蓝"
},
"Bakusou Josou Keikaku": {
"$type": "HashCrypt",
"Title": "爆走女装計画~もしも俺が女装させられてレディースに入隊させられたら~"
},
"Bitch Gal no Gachi Iki Acme": {
"$type": "HashCrypt",
"Title": "ビッチギャルのガチイキアクメ ~家庭教師の童貞巨根にハマり堕ち~ | Bitch Gyaru no Gachi Iki Acme"
},
"Bodatsu ~Kindan no Shokushu Soukan~": {
"$type": "HashCrypt",
"Title": "母奪~禁断の触手相姦~"
},
"Custom Reido 4/4+/V": {
"$type": "HashCrypt",
"Title": "カスタム隷奴 4/4+/V"
},
"Dare mo ga Kanojo o Neratteru": {
"$type": "HashCrypt",
"Title": "誰もが彼女を狙ってる。 | 众人觊觎的女友"
},
"Do-M Imouto O-nedari Kojin Lesson": {
"$type": "HashCrypt",
"Title": "ドM妹おねだり個人レッスン~私のSEX家庭教師お兄ちゃん~ | 义妹私教辅导~哥哥我是家庭教师"
},
"Fate/stay night": {
"$type": "FateCrypt"
},
"Fukashi na Aijou": {
"$type": "HashCrypt",
"Title": "不可視な愛情~透明なボクに感じるママ~"
},
"Gisobo, Choukyou Chuu": {
"$type": "HashCrypt",
"Title": "義祖母、調教中。 ~仲良しの秘訣はSMです。~"
},
"Hahadori ~Ochiteiku Haha no Eizou Kiroku~": {
"$type": "HashCrypt",
"Title": "母撮 ~堕ちていく母の映像記録~"
},
"Hame Pako Ou-sama Game!": {
"$type": "HashCrypt",
"Title": "ハメパコ王様ゲーム! ~合コン居酒屋編~"
},
"Hamedol Hakudaku Ochi": {
"$type": "HashCrypt",
"Title": "ハメドル白濁堕ち ~生中出しで、お仕事を貰っていいですか?~"
},
"Hardcore Teacher": {
"$type": "HashCrypt",
"Title": "ハードコア・ティーチャー ~絶対服従へのロジック~"
},
"Heliotrope -Sore wa Shi ni Itaru Kami no Ai-": {
"$type": "HashCrypt",
"Title": "ヘリオトロープ-それは死に至る神の愛-"
},
"Hentai Kyonyuu Nurse": {
"$type": "HashCrypt",
"Title": "HENTAI 巨乳ナース ~草食男子、治療計画!?~"
},
"Hime to Majin to Koi Suru Tamashii": {
"$type": "HashCrypt",
"Title": "ヒメと魔神と恋するたましぃ"
},
"Hito Yado Ippatsu Yarihamezon": {
"$type": "HashCrypt",
"Title": "一宿一発ヤリハメゾン -おじさんザーメンぜ~んぶちょうだい- | Isshuku Ippatsu Yarihamezon"
},
"Hitozuma Tenchou no Chitai Kinmu": {
"$type": "HashCrypt",
"Title": "人妻店長の痴態勤務 ~夜勤バイトの愉しみ方~"
},
"Honban Ari! Hitozuma Delivery R": {
"$type": "HashCrypt",
"Title": "本番有り! 人妻デリバリー ~どこかで見た美人妻たちを一人占め~"
},
"Hora, Sonna ni Koe o Morasu...": {
"$type": "HashCrypt",
"Title": "ほら、そんなに声を漏らすと彼氏にバレちまうぜ? ~エロゲ世界でモブの少女を寝取ってみた~"
},
"Ichizu ni Zettai Fukujuu na Imouto": {
"$type": "HashCrypt",
"Title": "一途に絶対服従な妹をめちゃくちゃにしてみた ~愛欲兄妹~"
},
"Iede Musume Tanetsuke Kanyuu": {
"$type": "HashCrypt",
"Title": "家出娘種付け姦誘~気弱なあの子を肉便器開発~"
},
"Ijou Seiai": {
"$type": "HashCrypt",
"Title": "異常性愛-妄想ビッチと真正ビッチ-"
},
"Immoral Joubo Hazard": {
"$type": "HashCrypt",
"Title": "インモラル・情母・ハザード"
},
"Immoral Love ~Tsuma no Tsureko ga Ore no Koibito~": {
"$type": "HashCrypt",
"Title": "インモラル・ラブ ~妻の連れ子が俺の恋人~"
},
"Imouto Shokushu Rape": {
"$type": "HashCrypt",
"Title": "妹触手レイプ ~復讐の処女貫通~"
},
"In'en no Yu ~Sandai no Okami-tachi to no Mikkou~": {
"$type": "HashCrypt",
"Title": "淫艶の湯 ~三代の女将達との密交~"
},
"In'yaku Izon Gakuen": {
"$type": "HashCrypt",
"Title": "淫薬依存学園~もっと…もっとちょうだい!~"
},
"Inaka no Muchi na Muchimuchi Musume": {
"$type": "HashCrypt",
"Title": "田舎の無知なむちむち娘"
},
"In! Joku! Pink Ranger!!": {
"$type": "HashCrypt",
"Title": "淫!辱!ピンクレンジャー!! ~堕ちた変身ヒロイン~"
},
"Inraku Counseling": {
"$type": "HashCrypt",
"Title": "淫落カウンセリング ~夫の目の前で、妻は本性に堕ちてゆく~"
},
"Inshi Reizoku": {
"$type": "HashCrypt",
"Title": "淫姉隷属 ~影に潜んだ愛欲と支配~"
},
"Jimi me na Jijo-san no Oshigoto Sex": {
"$type": "HashCrypt",
"Title": "地味めな侍女さんのお仕事セックス~お嬢様に代わってお相手します~"
},
"Juurin! Orc Gakuen!": {
"$type": "HashCrypt",
"Title": "蹂躙!オーク学園! ~転校生は褐色ビッチな女勇者!?~"
},
"Kagachi-sama Onagusame Tatematsurimasu": {
"$type": "HashCrypt",
"Title": "かがち様お慰め奉ります ~寝取られ村淫夜噺~"
},
"Kaguya-hime wa Babumi Tappuri no Loli BBA Deshita": {
"$type": "HashCrypt",
"Title": "かぐや姫はバブみたっぷりのロリBBAでした。 ~うさみみメイドと責められムコ殿~"
},
"Kahogo na Ryoubo no Shasei Kanri": {
"$type": "HashCrypt",
"Title": "カホゴな寮母の射精管理 ~ちゃんと我慢してくださいね?~"
},
"Kanpeki Seitokaichou no Himitsu no Seiheki": {
"$type": "HashCrypt",
"Title": "完璧生徒会長の秘密の性癖 ~高嶺の花の彼女をM女に開花させてやる~"
},
"Kareshi ni Naisho de Kairaku Ochi": {
"$type": "HashCrypt",
"Title": "彼氏に内緒で快楽堕ち ~隠れヤリサーのリア充種付痴育~"
},
"Kasshoku Cool Bitch Hitozuma no Seiyoku Kaishou": {
"$type": "HashCrypt",
"Title": "褐色クールビッチ人妻の性欲解消 ~今度は海でセックスレッスン!?~"
},
"Kasshoku Orient Bijo to Shujuu Seikou": {
"$type": "HashCrypt",
"Title": "褐色オリエント美女と主従性交 ~魔性のワガママ搾精契約~"
},
"Kazoku Choukyou": {
"$type": "HashCrypt",
"Title": "家族調教"
},
"Kore tte, Riajuu?": {
"$type": "HashCrypt",
"Title": "これって、リア充? ~黒ギャルが、ドーテーを教育するそうですよ~"
},
"Kouen no Shugo Kishi Kishar": {
"$type": "HashCrypt",
"Title": "紅炎の守護騎士キシャル~Guardian of Prominence Kishar~"
},
"Kuro Gyaru Musume": {
"$type": "HashCrypt",
"Title": "黒ギャル娘との淫欲相姦~翻弄される父親の性欲~"
},
"Little Hole": {
"$type": "HashCrypt",
"Title": "りとるほーる ~俺の娘がこんなに……なハズがない | Littlehole~我的女儿不可能这么……"
},
"Mama no Okugai Shuuchi Lesson": {
"$type": "HashCrypt",
"Title": "ママの屋外羞恥レッスン ~視線が快楽に変る時…~"
},
"Mama to no Ikisugi Ama Ama Seikatsu": {
"$type": "HashCrypt",
"Title": "ママとのイキすぎ甘々性活~いっぱい気持ちいいコト教えてあ・げ・る~"
},
"Manamusume wa, Mazo Seirei": {
"$type": "HashCrypt",
"Title": "愛娘は、マゾ性隷 ~娘だからって遠慮しないでね?~"
},
"Minarai Taimashi Maji de Ikimasu!": {
"$type": "HashCrypt",
"Title": "見習い退魔師 本気でイキますっ!"
},
"Mizu no Kakera ~Once Summer of Islet~": {
"$type": "MizukakeCrypt",
"Title": "みずのかけら -once summer of islet-"
},
"Momojiri Instructor Netori Lesson": {
"$type": "HashCrypt",
"Title": "桃尻インストラクター寝取りレッスン ~競泳水着でえろざんまい~"
},
"Namaiki JK ni Fukushuu no Seikatsu Shidou": {
"$type": "HashCrypt",
"Title": "ナマイキJKに復讐の性活指導 ~先生、お願いだからもう許して…~"
},
"Nantai Lesson": {
"$type": "HashCrypt",
"Title": "軟体レッスン ~いいなり彼女とひみつの放課後~"
},
"Nee♥Summer!": {
"$type": "HashCrypt",
"Title": "姉♥Summer! ~ねえ♥さまー!~"
},
"Nyotai-ka Panic!": {
"$type": "HashCrypt",
"Title": "女体化パニック! ~オンナのコのカラダってキモチイイ~"
},
"Ochiteyuku Seishoku Shukujo": {
"$type": "HashCrypt",
"Title": "堕ちてゆく聖職淑女~いけない、夫に無理矢理やらされていただけなのに感じちゃう~"
},
"Ojou-sama wa Gakuen no Seieki Benjo": {
"$type": "HashCrypt",
"Title": "お嬢様は学園の精液便所 ~寝取らせ・ぶっかけ・乱交生活日誌~"
},
"Omae no Tsuma wa, Ore no Inran Niku Yome": {
"$type": "HashCrypt",
"Title": "お前の妻は、オレの淫乱肉嫁 ~お隣さんは欲求不満でした~"
},
"Omana 2: Omaenchi Moeteruzo": {
"$type": "HashCrypt",
"Title": "おまな2 おまえんち萌えてるぞ"
},
"Oppai Cafe ~Oyako de Cos Chichi~": {
"$type": "HashCrypt",
"Title": "おっぱいカフェ ~母娘でコスちち~"
},
"Ore no Imouto wa Seijun Bitch": {
"$type": "HashCrypt",
"Title": "俺の妹は清純ビッチ ~親には秘密のハメハメ性活~"
},
"Ore no Imouto wa Kyou kara Do S": {
"$type": "HashCrypt",
"Title": "俺の妹は今日からドS ~お、お兄ちゃんなんか、あたしのペットにしてやるんだからっ~"
},
"Ore wa, Shokushu Breeder": {
"$type": "HashCrypt",
"Title": "オレは、触手ブリーダー ~寄生触手で苗床化する女たち~"
},
"Osananajimi ga Chichioya": {
"$type": "HashCrypt",
"Title": "幼馴染みが父親とデキていた件について ~おやじからの羞恥ネトリ調教~"
},
"Osananajimi wa, Kakure Do M": {
"$type": "HashCrypt",
"Title": "幼馴染は、隠れドM ~変態調教に誘ったらドハマりしちゃった~"
},
"Otto ni Ienai Gifu to no Kan'in": {
"$type": "HashCrypt",
"Title": "夫に言えない義父との姦淫 ~嫌なのに忘れられなくなりそう~"
},
"Oyako Koukan": {
"$type": "HashCrypt",
"Title": "母娘肛姦 ~私のお尻に染みついていく雄の匂い~"
},
"Oyako no Himitsu": {
"$type": "HashCrypt",
"Title": "父娘の秘密 ~妻に言えない親子の関係~"
},
"P.S. Anata o Kokoro kara Aishiteimasu": {
"$type": "HashCrypt",
"Title": "P.S. あなたを心から愛しています。~最期まで気づけなかった妻の苦しみ~"
},
"Papa, Dakishimete Ageru": {
"$type": "HashCrypt",
"Title": "パパ、抱きしめてあげる ~バブみな愛娘の母性に甘えて中出し三昧~"
},
"Papa Daisuki! to Itte Kure...": {
"$type": "HashCrypt",
"Title": "パパ大好き!と言ってくれ…~反抗期の娘を催眠アプリで狂愛しつけ~"
},
"Sakura Sakura": {
"$type": "HashCrypt",
"Title": "さくらさくら"
},
"Segare no Niizuma": {
"$type": "HashCrypt",
"Title": "せがれの新妻"
},
"Seiso na Ano Ko wa, Kakure Bitch": {
"$type": "HashCrypt",
"Title": "清楚なあの娘は、隠れビッチ ~いつでもどこでも欲情SEX~"
},
"Senden no Shugo Kishi Niina": {
"$type": "HashCrypt",
"Title": "閃電の守護騎士ニィナ"
},
"Shikijou Kyoudan": {
"$type": "HashCrypt",
"Title": "色情教団 | 妃神会秘史"
},
"Shirouto Yanmama, Kosatsu AV Debut": {
"$type": "HashCrypt",
"Title": "素人ヤンママ、個撮AVデビュー ~見てな、女はド胸だぜ!~"
},
"Shitenasasou de, Shiteiru Kanojo no Shiteinai Koto": {
"$type": "HashCrypt",
"Title": "してなさそうで、している彼女のしていない事~キミの初めてになってやる~"
},
"Shokushu Ouji no Nikuyome Sagashi": {
"$type": "HashCrypt",
"Title": "触手王子の肉嫁探し~母と姉弟の終わらない絶頂地獄~"
},
"Sobo to Boku": {
"$type": "HashCrypt",
"Title": "祖母と僕 ~おばあちゃん、なにかでちゃうよぉ~"
},
"Sorairo no Shizuku": {
"$type": "MizukakeCrypt",
"Title": "そらいろの雫"
},
"Sousei no Himegimi": {
"$type": "HashCrypt",
"Title": "双性の姫君 ~ふたなり姉妹と魔王の求愛~"
},
"Sweet ☆ Switch": {
"$type": "HashCrypt",
"Title": "すうぃ~と☆SwitcH ~まじわるシセンでとろけるカラダ~"
},
"Tanetsuke Dungeon": {
"$type": "HashCrypt",
"Title": "種付けダンジョン~褐色エルフ産卵アクメ~"
},
"Tawawa Oku-san x Happening Gym": {
"$type": "HashCrypt",
"Title": "たわわ奥さん×ハプニングジム ~むっちりボディとすけべなエクササイズ~"
},
"Temptation Naked": {
"$type": "HashCrypt"
},
"Tettei Anal Chiiku": {
"$type": "HashCrypt",
"Title": "徹底アナル恥育 ~こっちが、気持ち良すぎて…~"
},
"Toaru Jukujo no Hentai Choukyou": {
"$type": "HashCrypt",
"Title": "とある熟女の変態調教 ~老いてなお滴る秘蜜と悦楽~"
},
"Tonarizuma 2 ~Otto ja Dekinai Koto Ippai Shite~": {
"$type": "HashCrypt",
"Title": "隣妻2 ~夫じゃできないこといっぱいシて~"
},
"Tsuma no Sobo wa": {
"$type": "HashCrypt",
"Title": "妻の祖母は、まだまだ現役超美熟女~孫婿ちゃん、寂しい時にはいつでもいらっしゃい~"
},
"Tsuma to Musuko ni Barete": {
"$type": "HashCrypt",
"Title": "妻と息子にバレてはいけない背徳の媚熱 ~あやまちの密愛2~"
},
"Ubawareta Gakuen ~Wana ni Ochita Yuutousei~": {
"$type": "HashCrypt",
"Title": "奪われた学園 ~罠に落ちた優等生~"
},
"Uchi ni Tenshi ga Yari ni kita": {
"$type": "HashCrypt",
"Title": "ウチに天使がヤリに来た -爆乳天使のご奉仕性活-"
},
"Virgin Mama": {
"$type": "HashCrypt",
"Title": "ヴァージン・ママ ~息子のおねだりを拒みきれないコスプレ相姦~"
},
"Yome no Ane ga Kyonyuu Sugite": {
"$type": "HashCrypt",
"Title": "嫁の姉が巨乳過ぎて我慢できない ~義姉さんがこんなにエロかったなんて!"
},
"Yome no Imouto to no In'ai": {
"$type": "HashCrypt",
"Title": "嫁の妹との淫愛~妻に隠れて交わる夫と義妹~"
},
"Yome Sagashi ga Hakadori Sugite Yabai.": {
"$type": "HashCrypt",
"Title": "嫁探しが捗りすぎてヤバい。 | 新娘太好找了我很方!"
},
"Zettai Sakusei! Succubus-chan": {
"$type": "HashCrypt",
"Title": "絶対搾精! サキュバスちゃん"
}
}

View File

@@ -63,6 +63,7 @@ enum CryptType {
NoCrypt,
FateCrypt,
MizukakeCrypt,
HashCrypt,
}
#[derive(Clone, Debug, Deserialize)]
@@ -79,6 +80,7 @@ impl Schema {
CryptType::NoCrypt => Box::new(NoCrypt::new()),
CryptType::FateCrypt => Box::new(FateCrypt::new()),
CryptType::MizukakeCrypt => Box::new(MizukakeCrypt::new()),
CryptType::HashCrypt => Box::new(HashCrypt::new()),
}
}
}
@@ -186,8 +188,36 @@ macro_rules! seek_reader_impl {
};
}
macro_rules! seek_crypt_impl {
($crypt:ident, $reader:ident<$t:ident>) => {
macro_rules! seek_reader_key_impl {
($reader:ident<$t:ident>, $key:ty) => {
#[derive(msg_tool_macro::MyDebug)]
#[allow(dead_code)]
struct $reader<$t: Read> {
#[skip_fmt]
inner: $t,
/// Start offset of the current xp3 entry.
seg_start: u64,
seg_size: u64,
pos: u64,
key: $key,
}
impl<$t: Read> $reader<$t> {
pub fn new(inner: $t, seg: &Segment, key: $key) -> Self {
Self {
inner,
seg_start: seg.offset_in_file,
seg_size: seg.original_size,
pos: 0,
key,
}
}
}
seek_impl!($reader<$t>);
};
}
macro_rules! seek_crypt_base_impl {
($crypt:ident, $reader:ident) => {
#[derive(Debug)]
pub struct $crypt {}
impl $crypt {
@@ -219,6 +249,12 @@ macro_rules! seek_crypt_impl {
Ok(Box::new($reader::new(stream, cur_seg)))
}
}
};
}
macro_rules! seek_crypt_impl {
($crypt:ident, $reader:ident<$t:ident>) => {
seek_crypt_base_impl!($crypt, $reader);
seek_reader_impl!($reader<$t>);
};
}
@@ -267,6 +303,61 @@ impl<R: Read> Read for MizukakeCryptReader<R> {
}
}
#[derive(Debug)]
pub struct HashCrypt {}
impl HashCrypt {
pub fn new() -> Self {
Self {}
}
}
impl Crypt for HashCrypt {
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(HashCryptReader::new(
stream,
cur_seg,
entry.file_hash as u8,
)))
}
fn decrypt_with_seek<'a>(
&self,
entry: &Xp3Entry,
cur_seg: &Segment,
stream: Box<dyn ReadSeek + 'a>,
) -> Result<Box<dyn ReadSeek + 'a>> {
Ok(Box::new(HashCryptReader::new(
stream,
cur_seg,
entry.file_hash as u8,
)))
}
}
seek_reader_key_impl!(HashCryptReader<T>, u8);
impl<R: Read> Read for HashCryptReader<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;
}
self.pos += readed as u64;
Ok(readed)
}
}
#[test]
fn test_deserialize_crypt() {
for (key, schema) in CRYPT_SCHEMA.iter() {