Skip to content

Commit 1cd4443

Browse files
committed
Various fixes
1 parent b04a0cd commit 1cd4443

File tree

4 files changed

+59
-18
lines changed

4 files changed

+59
-18
lines changed

src/command/patch/assets_patcher.rs

+41-8
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ use walkdir::WalkDir;
55
use crate::command::patch::xml_patcher;
66

77
pub fn patch_assets(patch: &PathBuf, unpacked: &PathBuf, temp_dir: &PathBuf) -> anyhow::Result<PathBuf> {
8+
println!("Patching assets..");
89
let patched_assets = temp_dir.join("patched");
10+
std::fs::create_dir_all(&patched_assets)
11+
.context("Failed to create patched assets directory")?;
912

13+
// copy over original files and if they have a patch, apply the patch
1014
for file in WalkDir::new(unpacked) {
1115
let file = file.map_err(|e| anyhow::anyhow!("Failed to walk directory: {}", e))?;
1216
let rel_path = file.path().strip_prefix(unpacked)
@@ -28,7 +32,7 @@ pub fn patch_assets(patch: &PathBuf, unpacked: &PathBuf, temp_dir: &PathBuf) ->
2832
// check if file exists in patch directory
2933
let patch_file = patch.join(rel_path);
3034
if !patch_file.exists() { // patch file doesn't exist, so copy over the original
31-
copy_file(&file, rel_path, &patched_assets)?;
35+
copy_file(&file.path(), rel_path, &patched_assets)?;
3236
continue;
3337
}
3438

@@ -38,34 +42,63 @@ pub fn patch_assets(patch: &PathBuf, unpacked: &PathBuf, temp_dir: &PathBuf) ->
3842
// copy over the patch file if it's a png, csv or txt file
3943
// TODO: csv and txt patching
4044
if ext == OsStr::new("png") || ext == OsStr::new("csv") || ext == OsStr::new("txt") {
41-
copy_file(&file, rel_path, &patched_assets)?;
42-
} else if ext == OsStr::new("xml") || ext == OsStr::new("xml") {
45+
println!("Copying patch file for: {}", rel_path.display());
46+
copy_file(&patch_file.as_path(), rel_path, &patched_assets)?;
47+
} else if ext == OsStr::new("xml") || ext == OsStr::new("fnt") {
48+
println!("Patching xml file: {}", rel_path.display());
4349
patch_xml(&file, &patch_file, rel_path, &patched_assets)?;
4450
} else {
4551
anyhow::bail!("Unsupported file type: {}", patch_file.display());
4652
}
4753

4854
}
4955

56+
// Loop over any files newly added with the patch
57+
for file in WalkDir::new(patch) {
58+
let file = file.map_err(|e| anyhow::anyhow!("Failed to walk directory: {}", e))?;
59+
let rel_path = file.path().strip_prefix(patch)
60+
.context("Failed to strip prefix")?;
61+
let target = patched_assets.join(rel_path);
62+
let file_type = file.file_type();
63+
64+
// if file is a directory, just create it in the patched assets directory
65+
if file_type.is_dir() && !target.exists() {
66+
std::fs::create_dir_all(&target).context("Failed to create directory")?;
67+
continue;
68+
}
69+
70+
// skip symlinks etc.
71+
if !file_type.is_file() {
72+
continue;
73+
}
74+
75+
// copy over the file if it doesn't exist already
76+
if !target.exists() {
77+
println!("Adding new file: {}", rel_path.display());
78+
copy_file(&file.path(), rel_path, &patched_assets)?;
79+
}
80+
}
81+
5082
return Ok(patched_assets);
5183
}
5284

53-
/// Copies a file from the unpacked assets to the patched assets directory and makes sure the directory structure is created
54-
fn copy_file(file: &walkdir::DirEntry, rel_path: &Path, patched_assets: &PathBuf) -> anyhow::Result<()> {
85+
/// Copies a file from one of the input directories to the patched assets directory and makes sure
86+
/// the directory structure is created
87+
fn copy_file(file: &Path, rel_path: &Path, patched_assets: &PathBuf) -> anyhow::Result<()> {
5588
let output = patched_assets.join(rel_path);
5689
if let Some(parent) = output.parent() {
5790
std::fs::create_dir_all(parent).context("Failed to create directory")?;
5891
}
59-
std::fs::copy(file.path(), &output).context("Failed to copy file")?;
92+
std::fs::copy(file, &output).context("Failed to copy file")?;
6093
Ok(())
6194
}
6295

6396
/// Patches an XML file using the given patch file and writes the output to the patched assets directory
64-
fn patch_xml(file: &walkdir::DirEntry, patch_file: &PathBuf, rel_path: &Path, patched_assets: &PathBuf) -> anyhow::Result<()> {
97+
fn patch_xml(original: &walkdir::DirEntry, patch_file: &PathBuf, rel_path: &Path, patched_assets: &PathBuf) -> anyhow::Result<()> {
6598
let output = patched_assets.join(rel_path);
6699
if let Some(parent) = output.parent() {
67100
std::fs::create_dir_all(parent)
68101
.context("Failed to create directory")?;
69102
}
70-
xml_patcher::patch(file.path(), patch_file, &output)
103+
xml_patcher::patch(original.path(), patch_file, &output)
71104
}

src/command/patch/mod.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,19 @@ pub fn patch(args: &NewArgs, patch: &PathBuf, locale_mode: &I18nCompatMode) -> a
1818
anyhow::bail!("Patch directory {:?} does not exist", patch);
1919
}
2020

21-
let game_files = prepare_game_files(&patch)?;
21+
let game_files = prepare_game_files(&args.game)?;
2222

2323
let temp_dir = create_temp_dir();
24+
println!("Using temp directory: {}", temp_dir.display());
2425
let temp_unpacked = temp_dir.join("unpacked");
2526
std::fs::create_dir_all(&temp_unpacked)
2627
.context("Failed to create temp directory")?;
2728

28-
unpack::unpack_dat(args, &game_files.assets, &temp_unpacked)?;
29+
unpack::unpack_assets(args, &game_files.assets, &temp_unpacked)?;
2930

3031
patch_assets(patch, &temp_unpacked, &temp_dir)?;
3132

32-
unimplemented!()
33+
Ok(())
3334
}
3435

3536

@@ -41,13 +42,20 @@ pub struct GameFiles {
4142
}
4243

4344
fn prepare_game_files(game_dir: &PathBuf) -> anyhow::Result<GameFiles> {
45+
// if game_dir is not already PapersPlease_Data, append it
46+
let game_dir = if game_dir.ends_with("PapersPlease_Data") {
47+
game_dir.clone()
48+
} else {
49+
game_dir.join("PapersPlease_Data")
50+
};
51+
4452
if !game_dir.is_dir() {
4553
anyhow::bail!("Game directory {:?} does not exist", game_dir);
4654
}
4755

48-
let assets = prepare_file(game_dir, "sharedassets0.assets")?;
49-
let resources = prepare_file(game_dir, "sharedassets0.resource")?;
50-
let locale = prepare_file(game_dir, "StreamingAssets/loc/en.zip")?;
56+
let assets = prepare_file(&game_dir, "sharedassets0.assets")?;
57+
let resources = prepare_file(&game_dir, "sharedassets0.resource")?;
58+
let locale = prepare_file(&game_dir, "StreamingAssets/loc/en.zip")?;
5159

5260
Ok(GameFiles { assets, resources, locale })
5361
}

src/command/patch/xml_patcher.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ pub fn patch(original: &Path, patch: &PathBuf, output: &PathBuf) -> anyhow::Resu
2727
merge_to(&mut writer, first, &mut patch_index)
2828
.with_context(|| format!("Failed to patch {} with {}", original.display(), patch.display()))?;
2929
}
30-
31-
unimplemented!()
30+
31+
Ok(())
3232
}
3333

3434
type NodeIndex<'doc, 'input> = HashMap<String, HashMap<String, Node<'doc, 'input>>>;

src/main.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ enum Command {
5959
output: PathBuf,
6060

6161
/// How should the tool handle localized assets.
62-
#[arg(long, default_value = "None")]
62+
#[arg(long, default_value = "none")]
6363
i18n: I18nCompatMode,
6464
},
6565
/// Unpack assets from an Art.dat or unity asset bundle.
@@ -79,7 +79,7 @@ enum Command {
7979
patch: PathBuf,
8080

8181
/// How should the tool handle localized assets.
82-
#[arg(long, default_value = "None")]
82+
#[arg(long, default_value = "none")]
8383
i18n: I18nCompatMode,
8484
},
8585
}

0 commit comments

Comments
 (0)