Compare commits
4 Commits
bdd5d849eb
...
3f91386763
| Author | SHA1 | Date | |
|---|---|---|---|
|
3f91386763
|
|||
|
560562cc25
|
|||
|
f404f597c1
|
|||
|
b3126d1798
|
@@ -160,6 +160,7 @@ fn should_be_included(path: impl AsRef<Path>) -> bool {
|
||||
| "ilstrings"
|
||||
| "dlstrings"
|
||||
| "dll"
|
||||
| "swf"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ pub enum PluginTypeDescriptorEnum {
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct DependencyPluginType {
|
||||
#[serde(rename = "defaultType")]
|
||||
pub default_type: PluginType,
|
||||
pub patterns: DependencyPatternList,
|
||||
}
|
||||
@@ -129,7 +130,7 @@ pub struct DependencyPatternList {
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct DependencyPattern {
|
||||
pub dependencies: CompositeDependency,
|
||||
pub dependencies: Vec<CompositeDependency>,
|
||||
#[serde(rename = "type")]
|
||||
pub typ: PluginType,
|
||||
}
|
||||
|
||||
@@ -176,7 +176,11 @@ fn resolve_plugin_type(
|
||||
PluginTypeDescriptorEnum::PluginType(plugin_type) => plugin_type.name,
|
||||
PluginTypeDescriptorEnum::DependencyType(dependency_plugin_type) => {
|
||||
for dep in &dependency_plugin_type.patterns.pattern {
|
||||
if evaluate_dependency(&dep.dependencies, state, installed_plugins) {
|
||||
if dep
|
||||
.dependencies
|
||||
.iter()
|
||||
.all(|e| evaluate_dependency(e, state, installed_plugins))
|
||||
{
|
||||
return dep.typ.name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use std::{fs, path::Path};
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use anyhow::{Ok, anyhow};
|
||||
use log::error;
|
||||
use zip::ZipArchive;
|
||||
|
||||
@@ -29,6 +32,8 @@ pub fn unpack(archive_path: impl AsRef<Path>, extract_to: impl AsRef<Path>) -> a
|
||||
}
|
||||
}?;
|
||||
|
||||
unnest_dir(extract_to)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -53,3 +58,47 @@ fn unpack_rar(path: impl AsRef<Path>, to: impl AsRef<Path>) -> anyhow::Result<()
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Moves a directorys content into the parent if it is the only dir
|
||||
fn unnest_dir(path: impl AsRef<Path>) -> anyhow::Result<()> {
|
||||
let path = path.as_ref();
|
||||
|
||||
let Some(nested_dir) = check_nested_dir(path) else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
for entry in fs::read_dir(&nested_dir)? {
|
||||
let entry = entry?;
|
||||
let src = entry.path();
|
||||
let dest = path.join(entry.file_name());
|
||||
fs::rename(&src, &dest)?;
|
||||
}
|
||||
|
||||
fs::remove_dir(&nested_dir)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Check if the extracted archive has a single directory in it which contains the mod files
|
||||
fn check_nested_dir(path: impl AsRef<Path>) -> Option<PathBuf> {
|
||||
let path = path.as_ref();
|
||||
|
||||
let entries: Vec<_> = fs::read_dir(path).ok()?.filter_map(|e| e.ok()).collect();
|
||||
|
||||
if entries.len() == 1 {
|
||||
let entry = &entries[0];
|
||||
let entry_path = entry.path();
|
||||
|
||||
if entry_path
|
||||
.file_name()
|
||||
.is_some_and(|e| e == "Data" || e == "data")
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
if entry_path.is_dir() {
|
||||
return Some(entry_path);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
67
tests/data/fomod/moduleconfig/po3tweaks.xml
Normal file
67
tests/data/fomod/moduleconfig/po3tweaks.xml
Normal file
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://qconsulting.ca/fo3/ModConfig5.0.xsd">
|
||||
<moduleName>powerofthree's Tweaks</moduleName>
|
||||
<requiredInstallFiles>
|
||||
<folder source="Required" destination="" />
|
||||
</requiredInstallFiles>
|
||||
<installSteps order="Explicit">
|
||||
<installStep name="Main">
|
||||
<optionalFileGroups order="Explicit">
|
||||
<group name="DLL" type="SelectExactlyOne">
|
||||
<plugins order="Explicit">
|
||||
<plugin name="SSE v1.6.629+ ("Anniversary Edition")">
|
||||
<description>Select this if you are using Skyrim Anniversary Edition v1.6.629 or higher.</description>
|
||||
<files>
|
||||
<folder source="AE/SKSE/Plugins" destination="SKSE/Plugins" priority="0" />
|
||||
</files>
|
||||
<typeDescriptor>
|
||||
<dependencyType>
|
||||
<defaultType name="Optional" />
|
||||
<patterns>
|
||||
<pattern>
|
||||
<dependencies>
|
||||
<gameDependency version="1.6" />
|
||||
</dependencies>
|
||||
<type name="Recommended" />
|
||||
</pattern>
|
||||
<pattern>
|
||||
<dependencies>
|
||||
<gameDependency version="1.5" />
|
||||
</dependencies>
|
||||
<type name="Optional" />
|
||||
</pattern>
|
||||
</patterns>
|
||||
</dependencyType>
|
||||
</typeDescriptor>
|
||||
</plugin>
|
||||
<plugin name="SSE v1.5.97 ("Special Edition")">
|
||||
<description>Select this if you are using Skyrim Special Edition v1.5.97.</description>
|
||||
<files>
|
||||
<folder source="SE/SKSE/Plugins" destination="SKSE/Plugins" priority="0" />
|
||||
</files>
|
||||
<typeDescriptor>
|
||||
<dependencyType>
|
||||
<defaultType name="Optional" />
|
||||
<patterns>
|
||||
<pattern>
|
||||
<dependencies>
|
||||
<gameDependency version="1.6" />
|
||||
</dependencies>
|
||||
<type name="Optional" />
|
||||
</pattern>
|
||||
<pattern>
|
||||
<dependencies>
|
||||
<gameDependency version="1.5" />
|
||||
</dependencies>
|
||||
<type name="Recommended" />
|
||||
</pattern>
|
||||
</patterns>
|
||||
</dependencyType>
|
||||
</typeDescriptor>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</group>
|
||||
</optionalFileGroups>
|
||||
</installStep>
|
||||
</installSteps>
|
||||
</config>
|
||||
@@ -34,6 +34,7 @@ fn parse() {
|
||||
"example_04.xml",
|
||||
"example_05.xml",
|
||||
"banana.xml",
|
||||
"po3tweaks.xml"
|
||||
] {
|
||||
fomod::Config::load_from_file(get_xml(xml))
|
||||
.unwrap_or_else(|e| panic!("Parse for {xml} with {}", err_to_string(e)));
|
||||
|
||||
Reference in New Issue
Block a user