@@ -19,46 +19,124 @@ impl<T: TrackedFs> BpxInstaller<T> {
19
19
20
20
impl < T : TrackedFs > PackageInstaller < T > for BpxInstaller < T > {
21
21
async fn install_package (
22
- & self ,
23
- _package : & PackageReference ,
22
+ & mut self ,
23
+ package : & PackageReference ,
24
24
_package_deps : & [ PackageReference ] ,
25
25
package_dir : & Path ,
26
26
state_dir : & Path ,
27
27
_staging_dir : & Path ,
28
28
game_dir : & Path ,
29
- _is_modloader : bool ,
29
+ is_modloader : bool ,
30
30
) -> Result < ( ) , Error > {
31
- // Figure out the root bepinex directory. This should, in theory, always be the folder
32
- // that contains the winhttp.dll binary.
33
- let bepinex_root = WalkDir :: new ( package_dir)
34
- . into_iter ( )
35
- . filter_map ( |x| x. ok ( ) )
36
- . filter ( |x| x. path ( ) . is_file ( ) )
37
- . find ( |x| x. path ( ) . file_name ( ) . unwrap ( ) == "winhttp.dll" )
38
- . expect ( "Failed to find winhttp.dll within BepInEx directory." ) ;
39
- let bepinex_root = bepinex_root. path ( ) . parent ( ) . unwrap ( ) ;
31
+ if is_modloader {
32
+ // Figure out the root bepinex directory. This should, in theory, always be the folder
33
+ // that contains the winhttp.dll binary.
34
+ let bepinex_root = WalkDir :: new ( package_dir)
35
+ . into_iter ( )
36
+ . filter_map ( |x| x. ok ( ) )
37
+ . filter ( |x| x. path ( ) . is_file ( ) )
38
+ . find ( |x| x. path ( ) . file_name ( ) . unwrap ( ) == "winhttp.dll" )
39
+ . expect ( "Failed to find winhttp.dll within BepInEx directory." ) ;
40
+ let bepinex_root = bepinex_root. path ( ) . parent ( ) . unwrap ( ) ;
41
+
42
+ let bep_dir = bepinex_root. join ( "BepInEx" ) ;
43
+ let bep_dst = state_dir. join ( "BepInEx" ) ;
44
+
45
+ self . fs . dir_copy ( & bep_dir, & bep_dst) . await . unwrap ( ) ;
46
+
47
+ // Install top-level doorstop files.
48
+ let files = fs:: read_dir ( bepinex_root)
49
+ . unwrap ( )
50
+ . filter_map ( |x| x. ok ( ) )
51
+ . filter ( |x| x. path ( ) . is_file ( ) ) ;
52
+
53
+ for file in files {
54
+ let dest = game_dir. join ( file. path ( ) . file_name ( ) . unwrap ( ) ) ;
55
+ self . fs . file_copy ( & file. path ( ) , & dest, None ) . await ?;
56
+ }
57
+
58
+ return Ok ( ( ) ) ;
59
+ }
60
+
61
+ let state_dir = state_dir. canonicalize ( ) ?;
62
+ let full_name= format ! ( "{}-{}" , package. namespace, package. name) ;
63
+
64
+ let targets = vec ! [
65
+ ( "plugins" , true ) ,
66
+ ( "patchers" , true ) ,
67
+ ( "monomod" , true ) ,
68
+ ( "config" , false ) ,
69
+ ] . into_iter ( )
70
+ . map ( |( x, y) | ( Path :: new ( x) , y) ) ;
40
71
41
- let bep_dir = bepinex_root. join ( "BepInEx" ) ;
42
- let bep_dst = state_dir. join ( "BepInEx" ) ;
72
+ let default = state_dir. join ( "BepInEx/plugins" ) ;
73
+ for ( target, relocate) in targets {
74
+ // Packages may either have the target at their tld or BepInEx/target.
75
+ let src = match package_dir. join ( "BepInEx" ) . exists ( ) {
76
+ true => package_dir. join ( "BepInEx" ) . join ( target) ,
77
+ false => package_dir. join ( target) ,
78
+ } ;
79
+
80
+ // let src = package_dir.join(target);
81
+ let dest = state_dir. join ( "BepInEx" ) . join ( target) ;
43
82
44
- // self.fs.dir_copy(&bep_dir, &bep_dst).await.unwrap();
83
+ if !src. exists ( ) {
84
+ continue ;
85
+ }
45
86
46
- // Install top-level doorstop files.
47
- let files = fs:: read_dir ( bepinex_root)
48
- . unwrap ( )
87
+ if !dest. exists ( ) {
88
+ fs:: create_dir_all ( & dest) ?;
89
+ }
90
+
91
+ // Copy the directory contents of the target into the destination.
92
+ let entries = fs:: read_dir ( & src) ?
93
+ . filter_map ( |x| x. ok ( ) ) ;
94
+
95
+ for entry in entries {
96
+ let entry = entry. path ( ) ;
97
+
98
+ let entry_dest = match relocate {
99
+ true => dest. join ( & full_name) . join ( entry. file_name ( ) . unwrap ( ) ) ,
100
+ false => dest. join ( entry. file_name ( ) . unwrap ( ) ) ,
101
+ } ;
102
+
103
+ let entry_parent = entry_dest. parent ( ) . unwrap ( ) ;
104
+
105
+ if !entry_parent. is_dir ( ) {
106
+ fs:: create_dir_all ( entry_parent) ?;
107
+ }
108
+
109
+ if entry. is_dir ( ) {
110
+ self . fs . dir_copy ( & entry, & entry_dest) . await ?;
111
+ }
112
+
113
+ if entry. is_file ( ) {
114
+ self . fs . file_copy ( & entry, & entry_dest, None ) . await ?;
115
+ }
116
+ }
117
+ }
118
+
119
+ // Copy top-level files into the plugin directory.
120
+ let tl_files = fs:: read_dir ( package_dir) ?
49
121
. filter_map ( |x| x. ok ( ) )
50
122
. filter ( |x| x. path ( ) . is_file ( ) ) ;
51
123
52
- for file in files {
53
- let dest = game_dir. join ( file. path ( ) . file_name ( ) . unwrap ( ) ) ;
54
- // self.fs.file_copy(&file.path(), &dest, None).await?;
124
+ for file in tl_files {
125
+ let parent = default. join ( & full_name) ;
126
+ let dest = parent. join ( file. file_name ( ) ) ;
127
+
128
+ if !parent. exists ( ) {
129
+ fs:: create_dir_all ( & parent) ?;
130
+ }
131
+
132
+ self . fs . file_copy ( & file. path ( ) , & dest, None ) . await ?;
55
133
}
56
134
57
135
Ok ( ( ) )
58
136
}
59
137
60
138
async fn uninstall_package (
61
- & self ,
139
+ & mut self ,
62
140
_package : & PackageReference ,
63
141
_package_deps : & [ PackageReference ] ,
64
142
_package_dir : & Path ,
0 commit comments