mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-06-06 12:58:45 +08:00
Add SourireCrypt
Use case-insensitive method to compare game title
This commit is contained in:
@@ -4,6 +4,7 @@ use super::archive::*;
|
||||
use crate::ext::io::*;
|
||||
use crate::scripts::base::*;
|
||||
use crate::types::*;
|
||||
use crate::utils::case_insensitive_string::*;
|
||||
use crate::utils::encoding::*;
|
||||
use crate::utils::serde_base64bytes::*;
|
||||
use crate::utils::simple_pack::*;
|
||||
@@ -168,6 +169,7 @@ enum CryptType {
|
||||
PoringSoftCrypt,
|
||||
AppliqueCrypt,
|
||||
TokidokiCrypt,
|
||||
SourireCrypt,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
@@ -263,12 +265,13 @@ impl Schema {
|
||||
CryptType::PoringSoftCrypt => Box::new(PoringSoftCrypt::new(self.base.clone())),
|
||||
CryptType::AppliqueCrypt => Box::new(AppliqueCrypt::new(self.base.clone())),
|
||||
CryptType::TokidokiCrypt => Box::new(TokidokiCrypt::new(self.base.clone())),
|
||||
CryptType::SourireCrypt => Box::new(SourireCrypt::new(self.base.clone())),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref CRYPT_SCHEMA: BTreeMap<String, Schema> = {
|
||||
static ref CRYPT_SCHEMA: BTreeMap<CaseInsensitiveString, Schema> = {
|
||||
serde_json::from_str(&get_crypt_data()).expect("Failed to parse crypt.json")
|
||||
};
|
||||
static ref ALIAS_TABLE: HashMap<String, String> = {
|
||||
@@ -1031,6 +1034,20 @@ impl<R: Read> Read for TokidokiCryptReader<R> {
|
||||
}
|
||||
}
|
||||
|
||||
seek_crypt_filehash_key_impl!(SourireCrypt, SourireCryptReader<T>);
|
||||
|
||||
impl<R: Read> Read for SourireCryptReader<R> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||
let readed = self.inner.read(buf)?;
|
||||
let key = (self.key ^ 0xCD) 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() {
|
||||
|
||||
76
src/utils/case_insensitive_string.rs
Normal file
76
src/utils/case_insensitive_string.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use serde::Deserialize;
|
||||
use std::borrow::Borrow;
|
||||
use std::cmp::Ordering;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
/// A case-insensitive string wrapper. Can be used as a key in BTreeMap with a case-insensitive ordering.
|
||||
///
|
||||
/// WARN: Borrowing a &str/&String from this struct will not be case-insensitive. So getting a value from a BTreeMap with a &str/&String key is not ignore case. It just use it's original case.
|
||||
pub struct CaseInsensitiveString(String);
|
||||
|
||||
impl PartialEq for CaseInsensitiveString {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0.eq_ignore_ascii_case(&other.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<String> for CaseInsensitiveString {
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
self.0.eq_ignore_ascii_case(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<&str> for CaseInsensitiveString {
|
||||
fn eq(&self, other: &&str) -> bool {
|
||||
self.0.eq_ignore_ascii_case(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for CaseInsensitiveString {}
|
||||
|
||||
impl PartialOrd for CaseInsensitiveString {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for CaseInsensitiveString {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.0
|
||||
.to_ascii_lowercase()
|
||||
.cmp(&other.0.to_ascii_lowercase())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for CaseInsensitiveString {
|
||||
type Target = String;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for CaseInsensitiveString {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<str> for CaseInsensitiveString {
|
||||
fn borrow(&self) -> &str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<String> for CaseInsensitiveString {
|
||||
fn borrow(&self) -> &String {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for CaseInsensitiveString {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.0.fmt(f)
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@
|
||||
pub mod bit_stream;
|
||||
#[cfg(feature = "utils-blowfish")]
|
||||
pub mod blowfish;
|
||||
#[cfg(feature = "utils-case-insensitive-string")]
|
||||
pub mod case_insensitive_string;
|
||||
pub mod counter;
|
||||
#[cfg(feature = "utils-crc32")]
|
||||
pub mod crc32;
|
||||
|
||||
Reference in New Issue
Block a user