feat: chusanApp.exe patching

This commit is contained in:
2025-04-13 18:15:41 +00:00
parent 6270fce05f
commit 4247e19996
18 changed files with 406 additions and 187 deletions

View File

@ -20,7 +20,7 @@ pub enum PackageSource {
Local(Game)
}
#[derive(Clone, Default, Serialize, Deserialize)]
#[derive(Clone, Default, Serialize, Deserialize, Debug)]
#[allow(dead_code)]
pub struct Package {
pub namespace: String,
@ -31,11 +31,17 @@ pub struct Package {
pub source: PackageSource,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
pub enum Status {
Unchecked,
Unsupported,
OK(BitFlags<Feature>)
OK(BitFlags<Feature>, DLLs),
}
#[derive(Clone, PartialEq, Serialize, Deserialize, Debug)]
pub struct DLLs {
pub game: Option<String>,
pub amd: Option<String>
}
#[bitflags]
@ -54,7 +60,7 @@ pub enum Feature {
AmdDLL
}
#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize, Debug)]
#[allow(dead_code)]
pub struct Local {
pub version: String,
@ -64,7 +70,7 @@ pub struct Local {
pub icon: String,
}
#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize, Debug)]
#[allow(dead_code)]
pub struct Remote {
pub version: String,
@ -77,6 +83,14 @@ pub struct Remote {
pub dependencies: BTreeSet<PkgKey>,
}
impl PkgKey {
pub fn split(&self) -> Result<(String, String)> {
let (namespace, name) = self.0
.split_at(self.0.find("-").ok_or_else(|| anyhow!("Invalid package key"))?);
Ok((namespace.to_owned(), name[1..].to_owned())) // cut the hyphen
}
}
impl Package {
pub fn from_rainy(mut p: rainy::V1Package) -> Option<Package> {
if p.versions.len() == 0 {
@ -209,37 +223,50 @@ impl Package {
fn parse_status(mft: &PackageManifest) -> Status {
if mft.installers.len() == 0 {
return Status::OK(make_bitflags!(Feature::Mod));//Unchecked
} else if mft.installers.len() == 1 {
if let Some(serde_json::Value::String(id)) = &mft.installers[0].get("identifier") {
if id == "rainycolor" {
return Status::OK(make_bitflags!(Feature::Mod));
} else if id == "segatools" {
// Multiple features in the same dll (yubideck etc.) should be supported at some point
let mut flags = BitFlags::default();
if let Some(serde_json::Value::String(module)) = mft.installers[0].get("module") {
if module == "mu3hook" {
flags |= Feature::Mu3Hook;
} else if module == "chusanhook" {
flags |= Feature::ChusanHook;
} else if module == "amnet" {
flags |= Feature::AMNet | Feature::Aime;
} else if module == "aimeio" {
flags |= Feature::Aime;
} else if module == "mu3io" {
flags |= Feature::Mu3IO;
} else if module == "chuniio" {
flags |= Feature::ChuniIO;
} else if module == "mempatcher" {
flags |= Feature::Mempatcher;
} else if module == "game-dll" {
flags |= Feature::GameDLL;
return Status::OK(make_bitflags!(Feature::Mod), DLLs { game: None, amd: None }); //Unchecked
} else {
let mut flags = BitFlags::default();
let mut game_dll = None;
let mut amd_dll = None;
for installer in &mft.installers {
if let Some(serde_json::Value::String(id)) = installer.get("identifier") {
if id == "rainycolor" {
flags |= Feature::Mod;
} else if id == "segatools" {
// Multiple features in the same dll (yubideck etc.) should be supported at some point
if let Some(serde_json::Value::String(module)) = installer.get("module") {
if module == "mu3hook" {
flags |= Feature::Mu3Hook;
} else if module == "chusanhook" {
flags |= Feature::ChusanHook;
} else if module == "amnet" {
flags |= Feature::AMNet | Feature::Aime;
} else if module == "aimeio" {
flags |= Feature::Aime;
} else if module == "mu3io" {
flags |= Feature::Mu3IO;
} else if module == "chuniio" {
flags |= Feature::ChuniIO;
}
}
} else if id == "native-mod" {
if let Some(serde_json::Value::String(path)) = installer.get("dll-game") {
flags |= Feature::GameDLL;
flags |= Feature::Mod;
game_dll = Some(path.to_owned());
}
if let Some(serde_json::Value::String(path)) = installer.get("dll-amdaemon") {
flags |= Feature::AmdDLL;
flags |= Feature::Mod;
amd_dll = Some(path.to_owned());
}
} else {
return Status::Unsupported;
}
return Status::OK(flags);
}
}
log::debug!("{} parse result: {:?} {:?} {:?}", mft.name, flags, game_dll, amd_dll);
Status::OK(flags, DLLs { game: game_dll, amd: amd_dll })
}
Status::Unsupported
}
}