loadsmith_loader/loaders/
bepis_loader.rs1use std::path::PathBuf;
2
3use camino::Utf8Path;
4use loadsmith_install::{InstallRuleset, OwnedInstallRuleset, RouteRule};
5
6use crate::{BepInEx, LaunchArgs, LaunchContext, Loader, Result};
7
8#[derive(Debug, Clone)]
23pub struct BepisLoader {
24 inner: BepInEx,
25}
26
27impl BepisLoader {
28 fn new(inner: BepInEx) -> Self {
29 Self { inner }
30 }
31
32 pub fn with_rules(package_install_ruleset: OwnedInstallRuleset) -> Self {
34 Self::new(BepInEx::with_rules(package_install_ruleset))
35 }
36
37 pub fn with_default_rules() -> Self {
40 let mut inner = BepInEx::with_default_rules();
41 inner.insert_install_rule(
42 0,
43 RouteRule::new_with_target("renderer", Utf8Path::new("Renderer/BepInEx/plugins")),
44 );
45 Self::new(inner)
46 }
47}
48
49impl Loader for BepisLoader {
50 fn id(&self) -> &'static str {
51 "BepisLoader"
52 }
53
54 fn loader_install_rules(&self) -> InstallRuleset<'_> {
55 self.inner.loader_install_rules()
56 }
57
58 fn package_install_rules(&self) -> InstallRuleset<'_> {
59 self.inner.package_install_rules()
60 }
61
62 fn generate_launch_args(&self, ctx: &LaunchContext) -> Result<LaunchArgs> {
63 let bepinex_target = ctx.profile_path().join("BepInEx");
66
67 let mut args = LaunchArgs::new()
68 .arg("--hookfxr-enable")
69 .arg("--bepinex-target")
70 .arg(bepinex_target);
71
72 let preloader = super::bep_in_ex::bepinex_preloader_path(Some("Renderer"), ctx)?;
73 let preloader = ctx.format_proton_path(&preloader);
74
75 let (enable_prefix, target_prefix) = crate::doorstop::args(Some(4), ctx)?;
76 args = args
77 .arg(enable_prefix)
78 .arg("true")
79 .arg(target_prefix)
80 .arg(&*preloader);
81
82 Ok(args)
83 }
84
85 fn package_config_dirs(&self) -> Vec<PathBuf> {
86 vec!["BepInEx/config".into(), "Renderer/BepInEx/config".into()]
87 }
88
89 fn log_file(&self) -> Option<PathBuf> {
90 self.inner.log_file()
91 }
92
93 fn proxy_dll(&self) -> Option<PathBuf> {
94 self.inner.proxy_dll()
95 }
96}
97
98#[cfg(test)]
99mod tests {
100 use loadsmith_core::{PackageRef, Version};
101
102 use crate::{assert_map, assert_maps, test_util::MapFileTester};
103
104 use super::*;
105
106 #[test]
107 fn map_loader_files() {
108 assert_maps!(MapFileTester::new(
109 BepisLoader::with_default_rules(),
110 PackageRef::new("BepInEx-BepInExPack".to_string(), Version::new(5, 4, 2100)),
111 true,
112 ), [
113 "README.md" => None,
114 "BepInExPack/doorstop_config.ini" => "./doorstop_config.ini",
115 "BepInExPack/BepInEx/core/BepInEx.Preloader.dll" => "./BepInEx/core/BepInEx.Preloader.dll"
116 ])
117 }
118
119 #[test]
120 fn map_package_files() {
121 assert_maps!(MapFileTester::new(
122 BepisLoader::with_default_rules(),
123 PackageRef::new("Author-Name".to_string(), Version::new(1, 0, 0)),
124 false,
125 ), [
126 "README.md" => "BepInEx/plugins/Author-Name/README.md",
127 "nested/file.txt" => "BepInEx/plugins/Author-Name/file.txt",
128 "plugins/nested/file.txt" => "BepInEx/plugins/Author-Name/nested/file.txt",
129 "config/settings.json" => "BepInEx/config/settings.json",
130 "patchers/patcher.dll" => "BepInEx/patchers/Author-Name/patcher.dll",
131 "core/core.dll" => "BepInEx/core/Author-Name/core.dll",
132 "patch.mm.dll" => "BepInEx/monomod/Author-Name/patch.mm.dll",
133 "nested/patch.mm.dll" => "BepInEx/monomod/Author-Name/patch.mm.dll",
134 "monomod/patch.dll" => "BepInEx/monomod/Author-Name/patch.dll",
135 "monomod/nested/patch.dll" => "BepInEx/monomod/Author-Name/nested/patch.dll",
136 "renderer/patch.dll" => "Renderer/BepInEx/plugins/Author-Name/patch.dll",
137 ]);
138 }
139
140 #[test]
141 fn config_files_should_not_link() {
142 let loader = BepisLoader::with_default_rules();
143 let rules = loader.package_install_rules();
144
145 assert!(
146 !rules
147 .find_rule_for_path("config/settings.json")
148 .unwrap()
149 .use_links()
150 );
151 }
152
153 #[test]
154 fn package_dir_works() {
155 let loader = BepisLoader::with_default_rules();
156 let package = PackageRef::new("Author-Name".to_string(), Version::new(1, 0, 0));
157
158 let package_dir = loader.package_dir(&package).unwrap();
159
160 assert_eq!(package_dir, PathBuf::from("BepInEx/plugins/Author-Name"));
161 }
162}