45
45
46
46
import java .io .BufferedInputStream ;
47
47
import java .io .BufferedOutputStream ;
48
- import java .io .File ;
49
48
import java .io .IOException ;
50
49
import java .io .InputStream ;
51
50
import java .io .InputStreamReader ;
52
51
import java .net .MalformedURLException ;
53
52
import java .net .URL ;
54
53
import java .nio .file .Files ;
54
+ import java .nio .file .Path ;
55
55
import java .nio .file .Paths ;
56
56
import java .nio .file .StandardCopyOption ;
57
57
import java .security .MessageDigest ;
58
58
import java .util .ArrayList ;
59
- import java .util .Arrays ;
60
59
import java .util .HashMap ;
61
60
import java .util .HashSet ;
62
61
import java .util .List ;
@@ -94,54 +93,71 @@ public class DependencyLoaderImpl {
94
93
thread .setName ("Dependency Download Thread " + counter .incrementAndGet ());
95
94
return thread ;
96
95
});
97
- private static final File libDir ;
96
+ private static final Path libDir ;
97
+ private static final Path tempDir ;
98
98
99
- static {
100
-
101
- var homeDir = System . getProperty ( "minecraft.sharedDataDir" );
102
- if ( homeDir == null ) {
103
- homeDir = System . getenv ( "MINECRAFT_SHARED_DATA_DIR" );
104
- if ( homeDir == null ) {
105
- homeDir = FileUtil . getMinecraftHome (). getAbsolutePath ( );
99
+ private static void ensureExists ( Path directory ) {
100
+ if (! Files . exists ( directory )) {
101
+ try {
102
+ Files . createDirectories ( directory );
103
+ } catch ( IOException e ) {
104
+ LOG . fatal ( "Failed to create directory {}" , directory );
105
+ throw new RuntimeException ( "Failed to create directory " + directory , e );
106
106
}
107
107
}
108
- val modsDir = Paths .get (homeDir , "mods" ).toFile ();
109
- val oldLibDir = new File (modsDir , "falsepattern" );
110
- libDir = new File (homeDir , "falsepattern" );
111
- if (!libDir .exists ()) {
112
- if (!libDir .mkdirs ()) {
113
- LOG .fatal ("Failed to create directory {}" , libDir );
114
- throw new RuntimeException ("Failed to create directory " + libDir );
115
- }
108
+ }
109
+
110
+ static {
111
+ Path homeDir ;
112
+ String homeDirStr = System .getProperty ("minecraft.sharedDataDir" );
113
+ if (homeDirStr == null ) {
114
+ homeDirStr = System .getenv ("MINECRAFT_SHARED_DATA_DIR" );
115
+ }
116
+ if (homeDirStr == null ) {
117
+ homeDir = FileUtil .getMinecraftHome ().toPath ();
118
+ } else {
119
+ homeDir = Paths .get (homeDirStr );
116
120
}
117
- if (oldLibDir .exists ()) {
121
+ libDir = homeDir .resolve ("falsepattern" );
122
+ tempDir = homeDir .resolve (Paths .get ("logs" , "falsepattern_tmp" ));
123
+ ensureExists (libDir );
124
+ ensureExists (tempDir );
125
+ val oldLibDir = homeDir .resolve (Paths .get ("mods" , "falsepattern" ));
126
+ if (Files .exists (oldLibDir )) {
118
127
LOG .info ("Migrating old library folder. From: "
119
- + oldLibDir .getAbsolutePath ()
128
+ + oldLibDir .toAbsolutePath ()
120
129
+ ", To: "
121
- + libDir .getAbsolutePath ());
122
- val oldFiles = oldLibDir .listFiles ();
123
- if (oldFiles != null ) {
124
- for (val file : oldFiles ) {
130
+ + libDir .toAbsolutePath ());
131
+ try (val oldFiles = Files .list (oldLibDir )) {
132
+ oldFiles .forEach (file -> {
125
133
try {
126
- Files .move (file . toPath () ,
127
- libDir .toPath (). resolve (oldLibDir .toPath (). relativize (file . toPath () )),
134
+ Files .move (file ,
135
+ libDir .resolve (oldLibDir .relativize (file )),
128
136
StandardCopyOption .REPLACE_EXISTING );
129
137
} catch (IOException e ) {
130
- LOG .warn ("Failed to move file " + file .getName () + " to new dir! Deleting instead." );
138
+ LOG .warn ("Failed to move file " + file .getFileName () + " to new dir! Deleting instead." );
131
139
try {
132
- Files .deleteIfExists (file . toPath () );
140
+ Files .deleteIfExists (file );
133
141
} catch (IOException ex ) {
134
- LOG .warn ("Failed to delete file " + file .getPath () + "!" );
135
- file .deleteOnExit ();
142
+ LOG .warn ("Failed to delete file " + file + "!" , ex );
136
143
}
137
144
}
138
- }
145
+ });
146
+ } catch (IOException e ) {
147
+ LOG .warn ("Failed to iterate old library directory!" , e );
148
+ }
149
+ try {
150
+ Files .deleteIfExists (oldLibDir );
151
+ } catch (IOException e ) {
152
+ LOG .warn ("Failed to delete old library directory!" , e );
139
153
}
154
+ }
155
+ var oldCacheFile = libDir .resolve (".depscan_cache" );
156
+ if (Files .exists (oldCacheFile )) {
140
157
try {
141
- Files .deleteIfExists ( oldLibDir . toPath () );
158
+ Files .delete ( oldCacheFile );
142
159
} catch (IOException e ) {
143
- LOG .warn ("Failed to delete old library directory!" );
144
- oldLibDir .deleteOnExit ();
160
+ LOG .warn ("Failed to delete old depscan cache file!" , e );
145
161
}
146
162
}
147
163
}
@@ -168,8 +184,8 @@ private static String digest(String algo, byte[] data) {
168
184
}
169
185
170
186
@ SneakyThrows
171
- private static String hash (String algo , File file ) {
172
- byte [] data = Files .readAllBytes (file . toPath () );
187
+ private static String hash (String algo , Path file ) {
188
+ byte [] data = Files .readAllBytes (file );
173
189
switch (algo ) {
174
190
case "md5" :
175
191
algo = "MD5" ;
@@ -187,29 +203,31 @@ private static String hash(String algo, File file) {
187
203
return digest (algo , data );
188
204
}
189
205
190
- private static void checkedDelete (File file ) {
191
- if (!file .delete ()) {
206
+ private static void checkedDelete (Path file ) {
207
+ try {
208
+ Files .delete (file );
209
+ } catch (IOException e ) {
192
210
LOG .fatal ("Failed to delete file {}" , file );
193
- throw new RuntimeException ("Failed to delete file " + file );
211
+ throw new RuntimeException ("Failed to delete file " + file , e );
194
212
}
195
213
}
196
214
197
- private static synchronized void addToClasspath (File file ) {
215
+ private static synchronized void addToClasspath (Path file ) {
198
216
try {
199
217
val cl = (LaunchClassLoader ) DependencyLoaderImpl .class .getClassLoader ();
200
- cl .addURL (file .toURI ().toURL ());
201
- LOG .debug ("Injected file {} into classpath!" , file . getPath () );
218
+ cl .addURL (file .toUri ().toURL ());
219
+ LOG .debug ("Injected file {} into classpath!" , file );
202
220
} catch (Exception e ) {
203
- throw new RuntimeException ("Failed to add library to classpath: " + file .getAbsolutePath (), e );
221
+ throw new RuntimeException ("Failed to add library to classpath: " + file .toAbsolutePath (), e );
204
222
}
205
223
}
206
224
207
225
@ SneakyThrows
208
- private static void download (InputStream is , File target ) {
209
- if (target .exists ()) {
226
+ private static void download (InputStream is , Path target ) {
227
+ if (Files .exists (target )) {
210
228
return ;
211
229
}
212
- Internet .transferAndClose (is , new BufferedOutputStream (Files .newOutputStream (target . toPath () )));
230
+ Internet .transferAndClose (is , new BufferedOutputStream (Files .newOutputStream (target )));
213
231
}
214
232
215
233
public static void loadLibraries (Library ... libraries ) {
@@ -258,53 +276,55 @@ private static boolean scanForDepSpecs(URL source, List<URL> output) {
258
276
LOG .error ("Failed to open jar file {}" , source .getPath ());
259
277
}
260
278
} else {
261
- val dir = new File (fileName );
262
- if (!dir .exists () || !dir .isDirectory ()) {
279
+ val dir = Paths . get (fileName );
280
+ if (!Files .exists (dir ) || !Files .isDirectory (dir )) {
263
281
LOG .warn ("Skipping non-directory, nor jar source: {}" , source );
264
282
return false ;
265
283
}
266
284
//Scan directory for json in META-INF, add them to the list
267
- val metaInf = new File (dir , "META-INF" );
268
- if (!metaInf .exists () || !metaInf .isDirectory ()) {
269
- return false ;
270
- }
271
- val files = metaInf .listFiles ();
272
- if (files == null ) {
285
+ val metaInf = dir .resolve ("META-INF" );
286
+ if (!Files .exists (metaInf ) || !Files .isDirectory (metaInf )) {
273
287
return false ;
274
288
}
275
- for (val file : files ) {
276
- if (!file .getName ().endsWith (".json" )) {
277
- continue ;
278
- }
279
- try {
280
- output .add (file .toURI ().toURL ());
281
- found = true ;
282
- } catch (MalformedURLException e ) {
283
- LOG .error ("Failed to add json source {} to dependency source list: {}" , file .getName (), e );
284
- }
289
+ try (val files = Files .list (metaInf )) {
290
+ found = files .reduce (false , (prev ,file ) -> {
291
+ if (!file .endsWith (".json" )) {
292
+ return prev ;
293
+ }
294
+ try {
295
+ output .add (file .toUri ().toURL ());
296
+ return true ;
297
+ } catch (MalformedURLException e ) {
298
+ LOG .error ("Failed to add json source {} to dependency source list: {}" , file .getFileName (), e );
299
+ }
300
+ return prev ;
301
+ }, (a ,b ) -> a || b );
302
+ } catch (IOException e ) {
303
+ LOG .error ("Failed to open directory {}" , metaInf );
285
304
}
286
305
}
287
306
return found ;
288
307
}
289
308
290
- private static Stream <URL > grabSourceCandidatesFromFolder (File folder ) {
291
- if (!folder .exists () || !folder .isDirectory ()) {
292
- LOG .warn ("File does not exist or is not a directory: {}" , folder );
293
- } else {
294
- val files = folder .listFiles ();
295
- if (files == null ) {
296
- LOG .warn ("Folder is not readable: {}" , folder );
297
- } else {
298
- return Arrays .stream (files ).map (file -> {
299
- try {
300
- return file .toURI ().toURL ();
301
- } catch (MalformedURLException e ) {
302
- return null ;
303
- }
304
- }).filter (Objects ::nonNull );
305
- }
309
+ private static Stream <URL > grabSourceCandidatesFromFolder (Path folder ) {
310
+ if (!Files .exists (folder ) || !Files .isDirectory (folder )) {
311
+ return Stream .empty ();
312
+ }
313
+ Stream <Path > paths ;
314
+ try (val files = Files .list (folder )) {
315
+ //Lazy loading is bad here
316
+ paths = files .collect (Collectors .toSet ()).stream ();
317
+ } catch (IOException ignored ) {
318
+ return Stream .empty ();
306
319
}
307
- return Stream .empty ();
320
+
321
+ return paths .map (file -> {
322
+ try {
323
+ return file .toUri ().toURL ();
324
+ } catch (MalformedURLException e ) {
325
+ return null ;
326
+ }
327
+ }).filter (Objects ::nonNull );
308
328
}
309
329
310
330
private static <A , B , C > Stream <Pair <A , B >> flatMap (Pair <A , C > pair , Function <C , Stream <B >> mapper ) {
@@ -320,14 +340,14 @@ private static <A, B, C> Stream<Pair<A, B>> flatMap(Pair<A, C> pair, Function<C,
320
340
321
341
public static void scanDeps () {
322
342
LOG .debug ("Discovering dependency source candidates..." );
323
- val modsDir = new File ( FileUtil .getMinecraftHome (), "mods" );
324
- val mods1710Dir = new File ( modsDir , "1.7.10" );
343
+ val modsDir = FileUtil .getMinecraftHomePath (). resolve ( "mods" );
344
+ val mods1710Dir = modsDir . resolve ( "1.7.10" );
325
345
long start = System .currentTimeMillis ();
326
346
val urlsWithoutDeps = new HashSet <String >();
327
- val depCache = new File ( libDir , ".depscan_cache" );
328
- if (depCache .exists ()) {
347
+ val depCache = tempDir . resolve ( ".depscan_cache" );
348
+ if (Files .exists (depCache )) {
329
349
try {
330
- urlsWithoutDeps .addAll (Files .readAllLines (depCache . toPath () ));
350
+ urlsWithoutDeps .addAll (Files .readAllLines (depCache ));
331
351
} catch (IOException e ) {
332
352
LOG .error ("Could not read dependency scanner cache" , e );
333
353
}
@@ -344,7 +364,7 @@ public static void scanDeps() {
344
364
urlsWithoutDeps .add (candidate .toString ());
345
365
}
346
366
}
347
- try (val out = Files .newBufferedWriter (depCache . toPath () )) {
367
+ try (val out = Files .newBufferedWriter (depCache )) {
348
368
for (val noDep : urlsWithoutDeps ) {
349
369
out .append (noDep ).append (System .lineSeparator ());
350
370
}
@@ -500,7 +520,7 @@ private static class DependencyLoadTask {
500
520
private String artifact ;
501
521
private String mavenJarName ;
502
522
private String jarName ;
503
- private File file ;
523
+ private Path file ;
504
524
505
525
private void load () {
506
526
try {
@@ -586,11 +606,11 @@ private void setupPaths() {
586
606
mavenJarName =
587
607
String .format ("%s-%s%s.jar" , artifactId , preferredVersion , (suffix != null ) ? ("-" + suffix ) : "" );
588
608
jarName = groupId + "-" + mavenJarName ;
589
- file = new File ( libDir , jarName );
609
+ file = libDir . resolve ( jarName );
590
610
}
591
611
592
612
private boolean tryLoadingExistingFile () {
593
- if (!file .exists ()) {
613
+ if (!Files .exists (file )) {
594
614
return false ;
595
615
}
596
616
try {
@@ -694,7 +714,7 @@ private boolean tryDownloadFromMaven(String repo) {
694
714
private ChecksumStatus validateChecksum (String url ) throws IOException {
695
715
for (val checksumType : CHECKSUM_TYPES ) {
696
716
val checksumURL = url + "." + checksumType ;
697
- val checksumFile = new File ( libDir , jarName + "." + checksumType );
717
+ val checksumFile = libDir . resolve ( jarName + "." + checksumType );
698
718
LOG .debug ("Attempting to get {} checksum..." , checksumType );
699
719
val success = new AtomicBoolean (false );
700
720
Internet .connect (new URL (checksumURL ),
@@ -715,20 +735,20 @@ private ChecksumStatus validateChecksum(String url) throws IOException {
715
735
return ChecksumStatus .MISSING ;
716
736
}
717
737
718
- private ChecksumStatus validateChecksum (File file ) throws IOException {
738
+ private ChecksumStatus validateChecksum (Path file ) throws IOException {
719
739
for (val checksumType : CHECKSUM_TYPES ) {
720
- val checksumFile = new File ( libDir , jarName + "." + checksumType );
740
+ val checksumFile = libDir . resolve ( jarName + "." + checksumType );
721
741
LOG .debug ("Attempting to read {} checksum from file..." , checksumType );
722
- if (checksumFile .exists ()) {
742
+ if (Files .exists (checksumFile )) {
723
743
return getChecksumStatus (file , checksumType , checksumFile );
724
744
}
725
745
}
726
746
return ChecksumStatus .MISSING ;
727
747
}
728
748
729
- private ChecksumStatus getChecksumStatus (File file , String checksumType , File checksumFile ) throws IOException {
749
+ private ChecksumStatus getChecksumStatus (Path file , String checksumType , Path checksumFile ) throws IOException {
730
750
val fileHash = hash (checksumType , file );
731
- val referenceHash = new String (Files .readAllBytes (checksumFile . toPath () ));
751
+ val referenceHash = new String (Files .readAllBytes (checksumFile ));
732
752
if (!fileHash .equals (referenceHash )) {
733
753
LOG .error ("Failed {} checksum validation for {}." , checksumType , artifactLogName );
734
754
checkedDelete (file );
0 commit comments