Skip to content

Commit a536415

Browse files
committed
Reverted and added API changes
- Returned some removed functions and gave them a #[deprecated] tag to ease out their use. - Reverted the referenceflags naming to Legacy and Standard. - PathList and PartitionInfo are now user constructible - GamePaths automatic runtime folder detection will now consider case-sensitive systems
1 parent 3f46e85 commit a536415

File tree

12 files changed

+160
-69
lines changed

12 files changed

+160
-69
lines changed

examples/mount_game_files.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ use std::io::{stdin, Write};
22
use std::path::PathBuf;
33
use std::str::FromStr;
44
use std::{env, io};
5+
use itertools::Itertools;
56

67
use rpkg_rs::misc::resource_id::ResourceID;
78
use rpkg_rs::resource::partition_manager::{PartitionManager, PartitionState};
89
use rpkg_rs::resource::pdefs::{GamePaths, PackageDefinitionSource};
10+
use rpkg_rs::resource::resource_info::ResourceInfo;
11+
use rpkg_rs::resource::resource_partition::PatchId;
912
use rpkg_rs::resource::runtime_resource_id::RuntimeResourceID;
1013
use rpkg_rs::WoaVersion;
1114

@@ -116,6 +119,56 @@ fn main() {
116119

117120
let rrid = RuntimeResourceID::from_resource_id(&rid);
118121
println!("Try to find {}", rrid);
119-
package_manager.print_resource_changelog(&rrid)
122+
println!("Resource: {rrid}");
123+
124+
for partition in &package_manager.partitions {
125+
let mut last_occurence: Option<&ResourceInfo> = None;
126+
127+
let size =
128+
|info: &ResourceInfo| info.compressed_size().unwrap_or(info.size());
129+
130+
let changes = partition.resource_patch_indices(&rrid);
131+
let deletions = partition.resource_removal_indices(&rrid);
132+
let occurrences = changes
133+
.clone()
134+
.into_iter()
135+
.chain(deletions.clone().into_iter())
136+
.collect::<Vec<PatchId>>();
137+
138+
for occurence in occurrences.iter().sorted() {
139+
println!(
140+
"{}: {}",
141+
match occurence {
142+
PatchId::Base => {
143+
"Base"
144+
}
145+
PatchId::Patch(_) => {
146+
"Patch"
147+
}
148+
},
149+
partition.partition_info().filename(*occurence)
150+
);
151+
152+
if deletions.contains(occurence) {
153+
println!("\t- Removal: resource deleted");
154+
last_occurence = None;
155+
}
156+
157+
if changes.contains(occurence) {
158+
if let Ok(info) = partition.resource_info_from(&rrid, *occurence) {
159+
if let Some(last_info) = last_occurence {
160+
println!(
161+
"\t- Modification: Size changed from {} to {}",
162+
size(last_info),
163+
size(info)
164+
);
165+
} else {
166+
println!("\t- Addition: New occurrence, Size {} bytes", size(info))
167+
}
168+
last_occurence = Some(info);
169+
}
170+
}
171+
}
172+
}
120173
}
121174
}

src/misc/hash_path_list.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ pub enum PathListError {
2020
/// A rainbow table of hashed paths with associated paths.
2121
#[derive(Default, Debug)]
2222
pub struct PathList {
23-
entries: HashMap<RuntimeResourceID, Option<ResourceID>>,
23+
pub entries: HashMap<RuntimeResourceID, Option<ResourceID>>,
2424
}
2525

2626
impl PathList {

src/resource/package_builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -741,14 +741,14 @@ impl PackageBuilder {
741741

742742
for (_, flags) in &resource.references {
743743
flags
744-
.to_v1()
744+
.to_legacy()
745745
.write(writer)
746746
.map_err(PackageBuilderError::SerializationError)?;
747747
}
748748
} else {
749749
for (_, flags) in &resource.references {
750750
flags
751-
.to_v2()
751+
.to_standard()
752752
.write(writer)
753753
.map_err(PackageBuilderError::SerializationError)?;
754754
}

src/resource/partition_manager.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ pub struct PartitionState {
3838

3939
pub struct PartitionManager {
4040
runtime_directory: PathBuf,
41-
partition_infos: Vec<PartitionInfo>,
42-
pub partitions: Vec<ResourcePartition>,
41+
partition_infos: Vec<PartitionInfo>, //All potential partitions which could be mounted with this manager
42+
pub partitions: Vec<ResourcePartition>, //All mounted partitions
4343
}
4444

4545
impl PartitionManager {
@@ -138,7 +138,7 @@ impl PartitionManager {
138138

139139
partition
140140
.mount_resource_packages_in_partition_with_callback(runtime_directory, callback)
141-
.map_err(|e| PackageManagerError::PartitionError(partition_info.id(), e))?;
141+
.map_err(|e| PackageManagerError::PartitionError(partition_info.id, e))?;
142142

143143
if state_result.mounted {
144144
Ok(Some(partition))
@@ -211,7 +211,7 @@ impl PartitionManager {
211211
let partition = self
212212
.partitions
213213
.iter()
214-
.find(|partition| partition.partition_info().id() == partition_id);
214+
.find(|partition| partition.partition_info().id == partition_id);
215215

216216
if let Some(partition) = partition {
217217
match partition.read_resource(&rrid) {
@@ -228,15 +228,15 @@ impl PartitionManager {
228228
pub fn find_partition(&self, partition_id: PartitionId) -> Option<&ResourcePartition> {
229229
self.partitions
230230
.iter()
231-
.find(|partition| partition.partition_info().id() == partition_id)
231+
.find(|partition| partition.partition_info().id == partition_id)
232232
}
233233

234234
pub fn partitions_with_resource(&self, rrid: &RuntimeResourceID) -> Vec<PartitionId> {
235235
self.partitions
236236
.iter()
237237
.filter_map(|partition| {
238238
if partition.contains(rrid) {
239-
Some(partition.partition_info().id())
239+
Some(partition.partition_info().id.clone())
240240
} else {
241241
None
242242
}
@@ -265,7 +265,7 @@ impl PartitionManager {
265265
let partition = self
266266
.partitions
267267
.iter()
268-
.find(|partition| partition.partition_info().id() == *partition_id);
268+
.find(|partition| partition.partition_info().id == *partition_id);
269269

270270
if let Some(partition) = partition {
271271
match partition.get_resource_info(rrid) {
@@ -279,6 +279,12 @@ impl PartitionManager {
279279
}
280280
}
281281

282+
#[deprecated(since="1.0.0", note="prefer direct access through the partitions field")]
283+
pub fn partitions(&self) -> &Vec<ResourcePartition>{
284+
&self.partitions
285+
}
286+
287+
#[deprecated(since="1.1.0", note="please implement this yourself, it is out of scope for this struct")]
282288
pub fn print_resource_changelog(&self, rrid: &RuntimeResourceID) {
283289
println!("Resource: {rrid}");
284290

src/resource/pdefs/h2016_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ impl PackageDefinitionParser for H2016Parser {
9090
if let Ok(rid) =
9191
ResourceID::from_str(format!("{}.{}", &m[1], &m[2]).as_str())
9292
{
93-
current_partition.add_root(rid);
93+
current_partition.roots.push(rid);
9494
}
9595
}
9696
}

src/resource/pdefs/hm2_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ impl PackageDefinitionParser for HM2Parser {
5959
if let Ok(rid) =
6060
ResourceID::from_str(format!("{}.{}", &m[1], &m[2]).as_str())
6161
{
62-
current_partition.add_root(rid);
62+
current_partition.roots.push(rid);
6363
}
6464
}
6565
};

src/resource/pdefs/hm3_parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ impl PackageDefinitionParser for HM3Parser {
5050
if let Ok(rid) =
5151
ResourceID::from_str(format!("{}.{}", &m[1], &m[2]).as_str())
5252
{
53-
current_partition.add_root(rid);
53+
current_partition.roots.push(rid);
5454
}
5555
} else {
5656
return Err(PackageDefinitionError::UnexpectedFormat("ResourceID defined before partition, are you using the correct game version?".to_string()));

src/resource/pdefs/mod.rs

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ use crate::misc::resource_id::ResourceID;
1313
use crate::resource::pdefs::PackageDefinitionSource::{HM2, HM2016, HM3};
1414
use crate::resource::pdefs::PartitionType::{Dlc, LanguageDlc, LanguageStandard, Standard};
1515
use crate::resource::resource_partition::PatchId;
16-
use crate::WoaVersion;
16+
use crate::{utils, WoaVersion};
17+
use crate::resource::pdefs::GameDiscoveryError::InvalidRuntimePath;
1718

1819
pub mod h2016_parser;
1920
pub mod hm2_parser;
@@ -164,16 +165,16 @@ impl Display for PartitionId {
164165
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
165166
pub struct PartitionInfo {
166167
/// The name of the partition, if available.
167-
name: Option<String>,
168+
pub name: Option<String>,
168169
/// The parent partition's identifier, if any.
169-
parent: Option<PartitionId>,
170+
pub parent: Option<PartitionId>,
170171
/// The identifier of the partition.
171172
/// Example: "chunk9", "dlc12" or "dlc5langjp"
172-
id: PartitionId,
173+
pub id: PartitionId,
173174
/// The patch level of the partition. Note: This is used an an upper bound, any patch above this level will be ignored.
174-
patch_level: usize,
175+
pub patch_level: usize,
175176
/// The list of resource IDs associated with this partition.
176-
roots: Vec<ResourceID>,
177+
pub roots: Vec<ResourceID>,
177178
}
178179

179180
impl PartitionInfo {
@@ -191,26 +192,34 @@ impl PartitionInfo {
191192
self.id.to_filename(patch_index)
192193
}
193194

195+
#[deprecated(since="1.1.0", note="you can push to the roots field directly")]
194196
pub fn add_root(&mut self, resource_id: ResourceID) {
195197
self.roots.push(resource_id);
196198
}
199+
#[deprecated(since="1.1.0", note="prefer direct access through the roots field")]
197200
pub fn roots(&self) -> &Vec<ResourceID> {
198201
&self.roots
199202
}
200203

204+
#[deprecated(since="1.1.0", note="prefer direct access through the name field")]
201205
pub fn name(&self) -> &Option<String> {
202206
&self.name
203207
}
208+
209+
#[deprecated(since="1.1.0", note="prefer direct access through the parent field")]
204210
pub fn parent(&self) -> &Option<PartitionId> {
205211
&self.parent
206212
}
213+
214+
#[deprecated(since="1.1.0", note="prefer direct access through the id field")]
207215
pub fn id(&self) -> PartitionId {
208216
self.id.clone()
209217
}
218+
#[deprecated(since="1.1.0", note="prefer direct access through the patch_level field")]
210219
pub fn max_patch_level(&self) -> usize {
211220
self.patch_level
212221
}
213-
222+
214223
pub fn set_max_patch_level(&mut self, patch_level: usize) {
215224
self.patch_level = patch_level
216225
}
@@ -284,6 +293,9 @@ pub enum GameDiscoveryError {
284293

285294
#[error("No PROJECT_PATH found in thumbs.dat")]
286295
NoProjectPath,
296+
297+
#[error("The Runtime path cannot be found")]
298+
InvalidRuntimePath,
287299

288300
#[error("Failed to parse the thumbs.dat file: {0}")]
289301
FailedToParseThumbsFile(#[from] IniFileError),
@@ -310,9 +322,14 @@ impl GamePaths {
310322
.options()
311323
.get("RUNTIME_PATH")
312324
.ok_or(GameDiscoveryError::NoRuntimePath)?;
313-
let runtime_path = retail_directory
314-
.join(project_path)
325+
let mut runtime_path = retail_directory
326+
.join(project_path.replace("\\", "/"))
315327
.join(relative_runtime_path);
328+
if !runtime_path.exists(){
329+
runtime_path = retail_directory.join(project_path.replace("\\", "/")).join(utils::uppercase_first_letter(relative_runtime_path));
330+
}
331+
332+
runtime_path = runtime_path.canonicalize().map_err(|_| InvalidRuntimePath)?;
316333
let package_definition_path = runtime_path.join("packagedefinition.txt");
317334

318335
Ok(Self {

0 commit comments

Comments
 (0)